Поскольку вы хотите отсортировать по пути 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('.')))