Ramda 对嵌套对象的数组进行排序

Ramda sort array of nested object

我正在寻找使用 Ramda 对嵌套对象数组进行排序。我有一个数组:

const people = [
  { name: 'Emma', data:{ age: 70 }},
  { name: 'Peter', data:{  age: 78 }},
  { name: 'Mikhail', data:{  age: 62 }},
];

我想使用 Ramda 对以上数组进行排序。我得到了 this 但它对我不起作用。

非常感谢您的帮助。

因为你想按路径 data.age 排序,你可以使用 R.prop 从你的对象中获取道具 data 这将为你提供一个对象,然后使用 R.prop() 再次在那个对象上得到 age 属性。要创建执行此操作的函数,您可以使用 R.compose():

const byAge = R.ascend(R.compose(R.prop('age'), R.prop('data')));
const people = [
  { name: 'Emma', data:{ age: 70 }},
  { name: 'Peter', data:{  age: 78 }},
  { name: 'Mikhail', data:{  age: 62 }},
];

const peopleByYoungestFirst = R.sort(byAge, people);
console.log(peopleByYoungestFirst);
//=> [{"name":"Mikhail","data":{"age":62}},{"name":"Emma","data":{"age":70}},{"name":"Peter","data":{"age":78}}]
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js" integrity="sha256-buL0byPvI/XRDFscnSc/e0q+sLA65O9y+rbF+0O/4FE=" crossorigin="anonymous"></script>

要分解上面的组合函数,假设您有对象 obj,即:

obj = { name: 'Emma', data:{ age: 70 }}

执行R.prop('data')(obj)将得到:

{ age: 70 }

由于您对 returned 对象的 age 属性 感兴趣,您可以再次 运行 R.prop('age') 上述对象:

R.prop('age')({age: 70})

这将得到 70。所以上面一行可以写成:

R.prop('age')(R.prop('data')(obj))
^^^^^ f ^^^^^ ^^^^^^ g ^^^^^  ^ x

但是,此函数的问题在于它 return 不是一个我们可以将 obj 传递给它以从中得到 70 的函数。目前,它采用f(g(x))的形式,通过组合它,我们可以得到(f.g)(x)的形式,其中f.g将函数fg组合成产生新的功能。要在 Ramda 中组合,我们可以使用 R.compose():

R.compose(R.prop('age'), R.prop('data'))(obj)

这可以减少 eta 以删除示例中的 obj

这种方法可以概括为:

const {pipe, split, reverse, map, apply, compose, ascend} = R;
const makeSortFn = compose(ascend, pipe(split('.'), reverse, map(R.prop), apply(compose)));

const byAge = makeSortFn('data.age');
const people = [
  { name: 'Emma', data:{ age: 70 }},
  { name: 'Peter', data:{  age: 78 }},
  { name: 'Mikhail', data:{  age: 62 }},
];

const peopleByYoungestFirst = R.sort(byAge, people);
console.log(peopleByYoungestFirst);
//=> [{"name":"Mikhail","data":{"age":62}},{"name":"Emma","data":{"age":70}},{"name":"Peter","data":{"age":78}}]
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js" integrity="sha256-buL0byPvI/XRDFscnSc/e0q+sLA65O9y+rbF+0O/4FE=" crossorigin="anonymous"></script>

但相反,我更喜欢 ,它可以通过拆分字符串更容易地通用化:

R.sortBy(R.path(path_str.split('.')))

使用R.path得到data.age:

const sortByYoungest = R.sortBy(R.path(['data', 'age']))

const people = [{"name":"Emma","data":{"age":70}},{"name":"Peter","data":{"age":78}},{"name":"Mikhail","data":{"age":62}}];

const result = sortByYoungest(people);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js" integrity="sha256-buL0byPvI/XRDFscnSc/e0q+sLA65O9y+rbF+0O/4FE=" crossorigin="anonymous"></script>

获取一个页面,您可以使用 R.pipe 创建一个可重复使用的 sortByPath 函数:

const sortByPath = R.pipe(R.path, R.sortBy)
const sortByYoungest = sortByPath(['data', 'age'])

const people = [{"name":"Emma","data":{"age":70}},{"name":"Peter","data":{"age":78}},{"name":"Mikhail","data":{"age":62}}];

const result = sortByYoungest(people);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js" integrity="sha256-buL0byPvI/XRDFscnSc/e0q+sLA65O9y+rbF+0O/4FE=" crossorigin="anonymous"></script>