简体   繁体   English

嵌套对象的 Ramda 排序数组

[英]Ramda sort array of nested object

I am looking to sort an array of nested object using Ramda.我正在寻找使用 Ramda 对嵌套对象数组进行排序。 I have an array:我有一个数组:

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

I want to sort above array using Ramda.我想使用 Ramda 对数组进行排序。 I got this but it does not work for me.我得到了这个,但它对我不起作用。

Your help will be highly appreciated.您的帮助将不胜感激。

Use R.path to get the data.age :使用 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>

Taking a page from Nick's answer you can create a reusable sortByPath function using R.pipe:Nick 的回答中获取一页,您可以使用sortByPath创建一个可重用的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>

As you want to sort by the path data.age , you can get the prop data from your object using R.prop which will give you an object, and then use R.prop() again on that object to get the age property.由于您想按路径data.age排序,您可以使用R.prop从您的对象中获取道具data ,这将为您提供一个对象,然后在该对象上再次使用R.prop()以获取age属性。 To make a function which does this, you can use R.compose() :要创建一个执行此操作的函数,您可以使用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>

To break down the above compose function, say you have the object obj , which is:要分解上述 compose 函数,假设您有对象obj ,它是:

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

Performing R.prop('data')(obj) will give:执行R.prop('data')(obj)将给出:

{ age: 70 }

As you are interested in the age property of the returned object, you again can run R.prop('age') on the above object:由于您对返回对象的age属性感兴趣,您可以再次在上述对象上运行R.prop('age')

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

This will give 70 .这将给70 So above line can be written as:所以上面的行可以写成:

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

The issue with this function, however, is that it doesn't return a function which we can pass obj into to get 70 out of.然而,这个函数的问题在于它不返回一个函数,我们可以将obj传递给它以从中获得70 Currently, it takes the form of f(g(x)) , by composing it, we can get the form of (fg)(x) , where fg composes the functions f and g to produce a new function.目前,它采用f(g(x)) ,通过组合它,我们可以得到(fg)(x) ,其中fg组合函数fg以产生一个新函数。 To compose in Ramda, we can use R.compose() :要在R.compose()组合,我们可以使用R.compose()

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

This can be eta-reduced to remove the obj like it is in the example.这可以通过 eta-reduced 来删除obj就像在示例中一样。

This approach can be generalized to:这种方法可以推广到:

 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>

But instead, I would favour Ori's approach , which can be genralized much easier by splitting a string:但相反,我更喜欢Ori 的方法,通过拆分字符串可以更容易地概括:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM