这是一个家长列表,我想用ramda按第二个孩子的年龄对父母进行排序:
[
{
name: "Alicia",
age: "43",
children: [{
name: "Billy",
age: "3"
},
{
name: "Mary",
age: "8"
},
]
},
{
name: "Felicia",
age: "60",
children: [{
name: "Adrian",
age: "4"
},
{
name: "Joseph",
age: "5"
},
]
}
]
我该怎么做? 我尝试做一些类似的事情
parents.sort(
sortBy("-children.age"))
);
使用 R.sortBy
并使用函数 create with R.pipe
提取值。该函数获取带有 R.prop
的对象 的子数组,获取最后一个子数组 (R.last
(,获取带有 R.propOr
的age
(如果没有子项则返回 0(,并转换为 Number
。如果要颠倒顺序,可以使用R.negate
。
const { sortBy, pipe, prop, last, propOr } = R
const fn = sortBy(pipe(
prop('children'),
last,
propOr(0, 'age'),
Number,
// negate - if you want to reverse the order
))
const parents = [{"name":"Alicia","age":"43","children":[{"name":"Billy","age":"3"},{"name":"Mary","age":"8"}]},{"name":"Felicia","age":"60","children":[{"name":"Adrian","age":"4"},{"name":"Joseph","age":"5"}]}]
const result = fn(parents)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
在原版 JavaScript 中(对格式相对较差的输入做出一些假设(,使用 Array.prototype.sort
方法:
let parents = [ .... ]; // What you have above
parents = parents.sort((a, b) => {
return a.children[1].age - b.children[1].age; // Change - to + for ascending / descending
});
不过要小心 - 如果父母少于 2 个孩子会发生什么?
假设上面的JSON是手动生成的,包括语法错误,然后假设你的真实数据很好(一个父数组,每个父级都有一个children
的对象数组(,那么正常的JS排序就可以了:
const compareC2(parent1, parent2) {
let c1 = parent1.children;
let c2 = parent2.children;
if (!c1 || !c2) {
// what happens if someone has no children?
}
let l1 = c1.length;
let l2 = c2.length;
if (l1 === 0 || l2 === 0) {
// different symptom, but same question as above
}
if (l1 !== l2) {
// what happens when the child counts differ?
}
if (l1 !== 2) {
// what happens when there are fewer, or more than, 2 children?
}
// after a WHOLE LOT of assumptions, sort based on
// the ages of the 2nd child for each parent.
return c1[1].age - c2[1].age;
}
let sorted = parents.sort(compareC2);
我会将sortWith
与ascend
函数一起使用。使用 sortWith
可以定义第一排序顺序函数、第二排序顺序函数等。
const people = [
{
name: "Alicia",
age: "43",
children: [{
name: "Billy",
age: "3"
},
{
name: "Mary",
age: "8"
},
]
},
{
name: "Felicia",
age: "60",
children: [{
name: "Adrian",
age: "4"
},
{
name: "Joseph",
age: "5"
},
]
}
];
const by2ndChildAge = ascend(pathOr(0, ['children', 1, 'age']));
const by1stChildAge = ascend(pathOr(0, ['children', 0, 'age']));
console.log(sortWith([by2ndChildAge, by1stChildAge], people));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {sortWith, ascend, pathOr} = R;</script>
最简单的解决方案是将sortBy
与path
结合起来:
const sortBy2ndChildAge = sortBy(path(['children', 1, 'age']))
const people = [{name: "Alicia", age: "43", children: [{name: "Billy", age: "3"}, {name: "Mary", age: "8"}]}, {name: "Felicia", age: "60", children: [{name: "Adrian", age: "4"}, {name: "Joseph", age: "5"}]}]
console.log(sortBy2ndChildAge(people))
<script src="https://bundle.run/ramda@0.26.1"></script><script>
const {sortBy, path} = ramda </script>
其他人已经注意到了这一点,这有几个潜在的缺陷。 父母总是保证至少有两个孩子吗? 我们真的想要一个词典排序吗 - 即 '11' < '2'
-- 或者您想将这些值转换为数字?
解决这两个问题很容易:sortBy(compose(Number, pathOr(0, ['children', 1, 'age'])))
,但这取决于您要做什么。 如果您只是使用它来了解Ramda,那么sortBy
和path
都是有用的功能。 当您可以将要排序的项目转换为某种有序类型(字符串、数字、日期或使用数字valueOf
方法的任何内容(时,sortBy
很有用。 您提供该转换函数和值列表,它将按此排序。 path
只是对对象中嵌套属性列表的 null 安全读取。