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

问题描述 投票:0回答:5

这是一份父母的名单,我想按照他们的第二个孩子的年龄和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"))
            );
javascript arraylist ramda.js
5个回答
2
投票

使用R.sortBy并使用R.pipe创建的函数提取值。该函数使用R.prop获取对象的children数组,获取最后一个子项(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>

0
投票

在vanilla 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个孩子会怎么样?


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);

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>

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/[email protected]"></script><script>
const {sortBy, path} = ramda    </script>

其他人已经注意到,这有几个潜在的缺陷。父母总是保证至少有两个孩子吗?我们真的想要一个词典排序 - 即'11' < '2' - 或者你想将这些值转换为数字?

解决这两个问题很容易:sortBy(compose(Number, pathOr(0, ['children', 1, 'age']))),但这取决于你想要做什么。如果您只是用它来了解Ramda,那么sortBypath都是有用的功能。当你可以将要排序的项目转换为某些有序类型 - 字符串,数字,日期或任何带有数字sortBy方法的东西时,valueOf非常有用。您提供转换函数和值列表,它将按此排序。 path只是一个对象的嵌套属性列表的空安全读取。

© www.soinside.com 2019 - 2024. All rights reserved.