如何在 Ramda 中组合升序/降序 [英] How to compose an ascending/descending sort in 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
来有条件地ascend
或 descend
排序(基于 r.compose
code>sort.direction 属性),从而允许我删除 getSortedData
的最后一行和 reverse
数组操作.
我尝试了几种方法(比如用 prop
组合 ascend
,在组合中使用条件等),但它们都破坏了代码.
虽然现在运行良好,但谁能帮我让它更Ramda
ish?
更新 - 为后人在此处添加解决方案:
const getSortedData = (data) =>{返回 R.sort((sort.direction === 'ascending' ? R.ascend : R.descend)(R.compose(sort.isNumber ?Number.parseFloat : R.toLower,R.prop(sort.column))))(数据);}
我学到的东西:
R.sort
返回一个函数,而不是一个数组,因此您需要将data
作为参数发送给整个函数.R.ascend
/R.descend
也期望该函数作为参数,因此不应作为R.compose
的参数他们自己.
我想我会做这样的事情,将 ascend
或 descend
包裹在组合周围:>
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 Ramda
ish?
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:
R.sort
returns a function, and not an array, so you need to senddata
in as a parameter to the whole function.R.ascend
/R.descend
also expect the function as a paremeter, and therefore should not be a parameter ofR.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屋!