Ramda 按顺序排序且不区分大小写

Ramda sort with order and case insensitive

我现在需要对对象数组进行降序或升序排序,而结果不区分大小写。

我搜索并找到了一些实用的排序方式 ascending/descending。但是我需要的是顺序+不区分大小写的组合。

这是我的数组对象。

const arr = [{ title: 'AAA' }, { title: 'BBB' }, { title: 'aaa' }];

我需要的是一个柯里化函数,它采用排序配置并根据该配置对给定数组进行排序。

const ascending = sort({ by: 'title', order: 'asc' })(arr);
// output: [{ title: 'AAA' }, { title: 'aaa' }, { title: 'BBB' }]
const descending = sort({ by: 'title', order: 'desc' })(arr);
// output: [{ title: 'BBB' }, { title: 'aaa' }, { title: 'AAA' }]

我已经实现了我的排序功能的一个版本。但是我不能让它不区分大小写。

const sortDirection = R.ifElse(
  R.equals('descending'), 
  R.always(R.descend), 
  R.always(R.ascend)
);
const sort = config => items => R.sortWith(
  [ 
    R.compose(
      sortDirection(config.order), 
      R.prop
    )(config.by) 
  ], 
  items
);

一个answer from another question可以很容易地适应这个:

const arr = [{ title: 'BBB' }, { title: 'AAA' }, { title: 'aaa' }]

const makeSorter = ({order, isNumber, by}) => sort (
  (order === 'desc' ? descend : ascend) ( compose (
    isNumber ? Number.parseFloat : toLower,
    prop (by)
  ))
)

console .log (
  makeSorter ({ by: 'title', order: 'asc' }) (arr)
) //~> [{ title: 'AAA' }, { title: 'aaa' }, { title: 'BBB' }]

console .log (
  makeSorter ({ by: 'title', order: 'desc' }) (arr)
) //~> [{ title: 'BBB' }, { title: 'AAA' }, { title: 'aaa' }]
.as-console-wrapper {min-height: 100%; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
<script> const {sort, descend, ascend, compose, identity, toLower, prop } = R </script>

如果您想包含一个配置 属性 来确定灵敏度,您可以像这样添加它:

const makeSorter = ({order, isNumber, by, insensitive}) => sort (
  (order === 'desc' ? descend : ascend) ( compose (
    isNumber ? Number.parseFloat : insensitive ? toLower : identity,
    R.prop (by)
  ))
)

// later
makeSorter ({ by: 'title', order: 'asc', insensitive: true }) (arr)
//--------------------------------------------^

(请注意,如果以任何顺序给出 'aaa'、'AAA' 和 'BBB' 的标题,这些都不会准确地捕获您的预期输出,因为现代排序是稳定的,他们都会按照原始数组顺序对 'aaa' 和 'AAA' 进行排序,但是你的两个输出将它们交换了。)

根据@Scott Sauyet 的回答,我稍微修改了一下,看起来像这样。

const makeSorter = (config) => sort(
  (config.order === 'desc' ? descend : ascend) (
    compose (
      ifElse(is(String), toLower, identity),
      prop(config.by)
    )
  )
);

我只是想在处理字符串时将其设为小写。