Рамда сортирует массив вложенных объектов - PullRequest
1 голос
/ 31 марта 2020

Я хочу отсортировать массив вложенных объектов с помощью Ramda. У меня есть массив:

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

Я хочу отсортировать массив выше, используя Ramda. Я получил это , но оно не работает для меня.

Ваша помощь будет высоко оценена.

Ответы [ 2 ]

3 голосов
/ 31 марта 2020

Используйте 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>

Взяв страницу из Ответ Ника , вы можете создать функцию многократного использования sortByPath, используя R.pipe:

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>
1 голос
/ 31 марта 2020

Поскольку вы хотите отсортировать по пути data.age, вы можете получить реквизит data от вашего объекта, используя R.prop, который даст вам объект, а затем снова использовать 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 }

Поскольку вас интересует свойство age возвращаемого объекта, вы снова можете запустить R.prop('age') для вышеуказанного объекта:

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

This даст 70. Таким образом, строка выше может быть записана как:

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

Проблема с этой функцией, однако, заключается в том, что она не возвращает функцию, в которую мы можем передать obj, чтобы получить 70 из. В настоящее время он принимает форму f(g(x)), составляя его, мы можем получить форму (f.g)(x), где f.g составляет функции f и g для создания новой функции. Для сочинения в 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('.')))
...