如何在 Ramda 中组合升序/降序 [英] How to compose an ascending/descending sort in Ramda

查看:33
本文介绍了如何在 Ramda 中组合升序/降序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有排序标题表的 React 组件.此代码按计划工作:

//定义和导入...const [sort, setSort] = useState({column: 'rank', direction: 'ascending', isNumber: true});const handleSort = (column, isNumber = false) =>() =>{让方向 = (sort.column !== column) ?'升序' : (sort.direction === '升序' ? '降序' : '升序');setSort({column, direction, isNumber});};const getSortedData = (数据) =>{让排序 = R.sortBy(R.compose(sort.isNumber ?Number.parseFloat : R.toLower,R.prop(sort.column)),数据);返回 sort.direction === '升序' ?排序 : sorted.reverse();}//组件的其余部分...

但是,我确信有一种方法可以使用 R.compose 来有条件地ascenddescend 排序(基于 r.composecode>sort.direction 属性),从而允许我删除 getSortedData 的最后一行和 reverse 数组操作.

我尝试了几种方法(比如用 prop 组合 ascend,在组合中使用条件等),但它们都破坏了代码.

虽然现在运行良好,但谁能帮我让它更Ramdaish?

更新 - 为后人在此处添加解决方案:

const getSortedData = (data) =>{返回 R.sort((sort.direction === 'ascending' ? R.ascend : R.descend)(R.compose(sort.isNumber ?Number.parseFloat : R.toLower,R.prop(sort.column))))(数据);}

我学到的东西:

  1. R.sort 返回一个函数,而不是一个数组,因此您需要将 data 作为参数发送给整个函数.
  2. R.ascend/R.descend 也期望该函数作为参数,因此不应作为 R.compose 的参数他们自己.

解决方案

我想我会做这样的事情,将 ascenddescend 包裹在组合周围:

const makeSorter = (sortConfig) =>R.sort ((sortConfig.direction === 'descending' ? R.descend : R.ascend) ( R.compose (sortConfig.isNumber ?Number.parseFloat : R.toLower,R.prop (sortConfig.column))))常量人 = [{名称:'弗雷德',年龄:25},{名称:'巴尼',年龄:28},{名称:'威尔玛',年龄:29},{名称:'贝蒂',年龄:22}]const byName = {direction: 'descending', column: 'name', isNumber: false}const getSortedData = makeSorter(byName)控制台 .log (getSortedData(人))const byAge = {direction: 'ascending', column: 'age', isNumber: true}控制台 .log (makeSorter(按年龄)(人))

<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

我个人更喜欢用解构来编写它,例如:

const makeSorter = ({direction, isNumber, column}) =>R.sort ((direction === 'descending' ? R.descend : R.ascend) ( R.compose (是号码?Number.parseFloat : R.toLower,R.prop(列))))

但这并没有改变任何基本的东西.

I have a React component with a sorting headers table. This code works as planned:

  //definitions and imports...
  const [sort, setSort] = useState({column: 'rank', direction: 'ascending', isNumber: true});

  const handleSort = (column, isNumber = false) => () => {
    let direction = (sort.column !== column) ? 'ascending' : (sort.direction === 'ascending' ? 'descending' : 'ascending');
    setSort({column, direction, isNumber});
  };

  const getSortedData = (data) => {
    let sorted = R.sortBy(
      R.compose(
        sort.isNumber ? Number.parseFloat : R.toLower,
        R.prop(sort.column)
      ),
      data
    );
    return sort.direction === 'ascending' ? sorted : sorted.reverse();
  }
 //rest of the component...

However, I'm sure there's a way to use R.compose to conditionally ascend or descend the sort (based on the sort.direction property), and thus allow me to remove the last line of getSortedData and the reverse array op.

I tried several things (like composing ascend with prop, using the conditional in the compose etc.), but it all breaks down the code.

While it works well now, can anyone help me make it more Ramdaish?

Update - adding the solution here for posterity's sake:

const getSortedData = (data) => {
  return R.sort(
    (sort.direction === 'ascending' ? R.ascend : R.descend)(
      R.compose(
        sort.isNumber ? Number.parseFloat : R.toLower,
        R.prop(sort.column)
      )
    )
  )(data);
}

Things I've learned:

  1. R.sort returns a function, and not an array, so you need to send data in as a parameter to the whole function.
  2. R.ascend/R.descend also expect the function as a paremeter, and therefore should not be a parameter of R.compose on their own.

解决方案

I think I would do something like this, wrapping ascend or descend around the composition:

const makeSorter = (sortConfig) => R.sort (
  (sortConfig.direction === 'descending' ? R.descend : R.ascend) ( R.compose (
    sortConfig.isNumber ? Number.parseFloat : R.toLower,
    R.prop (sortConfig.column)
  ))
)

const people = [
  {name: 'fred', age: 25},
  {name: 'barney', age: 28},
  {name: 'wilma', age: 29},
  {name: 'betty', age: 22}
]

const byName = {direction: 'descending', column: 'name', isNumber: false}

const getSortedData = makeSorter(byName)

console .log (
  getSortedData (people)
)

const byAge = {direction: 'ascending', column: 'age', isNumber: true}

console .log (
  makeSorter (byAge) (people)
)

<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

I would personally prefer to write it with destructuring, as such:

const makeSorter = ({direction, isNumber, column}) => R.sort (
  (direction === 'descending' ? R.descend : R.ascend) ( R.compose (
    isNumber ? Number.parseFloat : R.toLower,
    R.prop (column)
  ))
)

but that doesn't change anything fundamental.

这篇关于如何在 Ramda 中组合升序/降序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆