Comparators turn any comparing function into a sorting function, without fretting browser inconsistencies. (5 min. read)
比较器将任何比较函数转换为排序函数,而不会影响浏览器的不一致性(5分钟(阅读)

Ascend and Descend #

You won’t need these as often as the main sorting functions, but they can be useful in some scenarios.
The functions we just saw, ascend/descend, are comparators. They take a function to apply against each value.
Here’s a sort by height.

  1. import { ascend, sort } from 'ramda';
  2. const people = [{
  3. height: 23
  4. }, {
  5. height: 230
  6. }, {
  7. height: 2.3
  8. }];
  9. const getHeight = (x) => x.height;
  10. const byHeight = ascend(getHeight);
  11. const result = sort(byHeight, people);
  12. console.log({ result });
  13. { result: [ { height: 2.3 }, { height: 23 }, { height: 230 } ] }

Ramda’s prop function can replace the getHeight function.

  1. import { ascend, prop, sort } from 'ramda';
  2. const people = [{
  3. height: 23
  4. }, {
  5. height: 230
  6. }, {
  7. height: 2.3
  8. }];
  9. const byHeight = ascend(prop('height'));
  10. const result = sort(byHeight, people);
  11. console.log({ result });
  12. { result: [ { height: 2.3 }, { height: 23 }, { height: 230 } ] }

And path lets you easily compare things, no matter how nested their properties are.

  1. import { ascend, path, sort } from 'ramda';
  2. const people = [{
  3. name: 'I am second',
  4. metadata: {
  5. attributes: {
  6. height: {
  7. value: 23
  8. }
  9. }
  10. }
  11. }, {
  12. name: 'I am last',
  13. metadata: {
  14. attributes: {
  15. height: {
  16. value: 230
  17. }
  18. }
  19. }
  20. }, {
  21. name: 'I am first',
  22. metadata: {
  23. attributes: {
  24. height: {
  25. value: 2.3
  26. }
  27. }
  28. }
  29. }];
  30. const getHeight = path(['metadata', 'attributes', 'height', 'value']);
  31. const byHeight = ascend(getHeight);
  32. const result = sort(byHeight, people);
  33. console.log(result);
  34. [ { name: 'I am first', metadata: { attributes: [Object] } },
  35. { name: 'I am second', metadata: { attributes: [Object] } },
  36. { name: 'I am last', metadata: { attributes: [Object] } } ]

https://ramdajs.com/docs/#path 加强版的prop

path Object 取出对象的某个属性

[Idx] → {a} → a | Undefined
Idx = String | Int
Parameters
Added in v0.2.0
Retrieve the value at a given path.
See also prop, nth.

  1. R.path(['a', 'b'], {a: {b: 2}}); //=> 2
  2. R.path(['a', 'b'], {c: {b: 2}}); //=> undefined
  3. R.path(['a', 'b', 0], {a: {b: [1, 2, 3]}}); //=> 1
  4. R.path(['a', 'b', -2], {a: {b: [1, 2, 3]}}); //=> 2

https://ramdajs.com/docs/#nth 取出list的某一项

nth

Number → [a] → a | Undefined
Number → String → String
Parameters
Added in v0.1.0
Returns the nth element of the given list or string. If n is negative the element at index length + n is returned.

  1. const list = ['foo', 'bar', 'baz', 'quux'];
  2. R.nth(1, list); //=> 'bar'
  3. R.nth(-1, list); //=> 'quux'
  4. R.nth(-99, list); //=> undefined
  5. R.nth(2, 'abc'); //=> 'c'
  6. R.nth(3, 'abc'); //=> ''

Lower-Level Comparator #

Ramda also has a comparator function. It creates comparator functions out of regular functions that compare two elements.
This function, for example…
低电平比较器#
拉姆达还有一个比较器功能。
它从比较两个元素的常规函数中创建比较器函数。
这个函数,例如…

  1. const byHeight = (a, b) => a.height > b.height;

…works with sort in modern browsers.

  1. import { sort } from 'ramda';
  2. const people = [{ height: 20 }, { height: 10 }];
  3. const byHeight = (a, b) => a.height > b.height;
  4. const result = sort(byHeight, people);
  5. console.log({ result });
  6. { result: [ { height: 10 }, { height: 20 } ] }

But since byHeight returns a boolean, older browsers like Internet Explorer won’t sort people correctly. Older browsers require your comparator to return a number!
See this StackOverflow answer for more details.
A proper comparator looks like this
但由于byHeight返回一个布尔值,像InternetExplorer这样的旧浏览器无法正确地对人进行排序。
较旧的浏览器要求您的比较器返回一个数字!
有关更多详细信息,请参阅此答案。 一个合适的比较器如下所示

  1. const byHeight = (a, b) => {
  2. if (a.height > b.height) {
  3. return 1;
  4. }
  5. if (a.height < b.height) {
  6. return -1;
  7. }
  8. return 0;
  9. };

Allowing this sort to work everywhere.

  1. import { sort } from 'ramda';
  2. const people = [{ height: 20 }, { height: 10 }];
  3. const byHeight = (a, b) => {
  4. if (a.height > b.height) {
  5. return 1;
  6. }
  7. if (a.height < b.height) {
  8. return -1;
  9. }
  10. return 0;
  11. };
  12. const result = sort(byHeight, people);
  13. console.log({ result });

A bit verbose. Fortunately, Ramda turns any comparison function into a proper comparator. All we need is the comparator function.
Take your original byHeight function and flip > to <…
有点冗长。
幸运的是,Ramda将任何比较函数转换为适当的比较器。
我们所需要的只是比较器函数。
使用原始的byHeight功能,
然后将>翻转到<…

  1. const byHeight = (a, b) => a.height < b.height;

And wrap it in comparator. I’d prefer renaming it so the comparator function can be named byHeight. 然后用比较器把它包起来。我更喜欢将其重命名,以便比较器函数可以按高度命名。

  1. // rename this
  2. const compareHeights = (a, b) => a.height < b.height;
  3. // giving this a proper name
  4. const byHeight = comparator(compareHeights)

Now use it.

  1. import { comparator, sort } from 'ramda';
  2. const people = [{ height: 20 }, { height: 10 }];
  3. const compareHeights = (a, b) => a.height < b.height;
  4. const byHeight = comparator(compareHeights);
  5. const result = sort(byHeight, people);
  6. console.log({ result });

https://ramdajs.com/docs/#comparator 兼容ie

((a, b) → Boolean) → ((a, b) → Number)
Parameters
Added in v0.1.0
Makes a comparator function out of a function that reports whether the first element is less than the second.
((a,b)→ 布尔值)→ ((a、 (b)→ (数字) 参数 添加到v0.1.0中 从报告第一个元素是否小于第二个元素的函数中生成比较器函数。

  1. const byAge = R.comparator((a, b) => a.age < b.age);
  2. const people = [
  3. { name: 'Emma', age: 70 },
  4. { name: 'Peter', age: 78 },
  5. { name: 'Mikhail', age: 62 },
  6. ];
  7. const peopleByIncreasingAge = R.sort(byAge, people);
  8. //=> [{ name: 'Mikhail', age: 62 },{ name: 'Emma', age: 70 }, { name: 'Peter', age: 78 }]