如何使用ramda按数组对象中的最后一项排序

时间:2019-04-03 18:29:12

标签: javascript arraylist ramda.js

这是父母的名单,我想按拉姆达的年龄,按父母的第二个孩子的年龄进行排序:

[
  {
    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"))
            );

5 个答案:

答案 0 :(得分:2)

使用R.sortBy并使用R.pipe创建的函数提取值。该函数使用R.prop获取对象的子节点数组,获取最后一个子节点(R.last),使用age获取R.propOr(如果没有子节点则返回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>

答案 1 :(得分:0)

使用Array.prototype.sort方法在普通JavaScript(对格式相对较差的输入进行一些假设)中

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个会怎样?

答案 2 :(得分:0)

假设上面的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);

答案 3 :(得分:0)

我将sortWithascend函数一起使用。使用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>

答案 4 :(得分:0)

我认为,最简单的解决方案是将sortBypath结合使用:

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,那么sortBypath都是有用的函数。当您可以将要排序的项目转换为某种有序类型时,sortBy很有用-字符串,数字,日期或任何带有数字valueOf方法的内容。您提供该转换函数和值列表,它将按此排序。 path只是对对象中的嵌套属性列表的null安全读取。