我有一个带有排序标题表的React组件。该代码按计划工作:
//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...
但是,我确定有一种方法可以使用R.compose
来有条件地对ascend
或descend
进行排序(基于sort.direction
属性),从而允许我删除getSortedData
的最后一行和reverse
数组op。
我尝试了几种方法(例如,将ascend
与prop
一起使用,并使用compose中的条件等等),但这都破坏了代码。
虽然现在效果很好,但是有人可以帮我更Ramda
吗?
更新-为子孙后代在此处添加解决方案:
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);
}
我学到的东西:
R.sort
返回一个函数,而不是数组,因此您需要将data
作为参数发送给整个函数。R.ascend
/ R.descend
也希望该函数用作参数,因此不应单独将其作为R.compose
的参数。答案 0 :(得分:2)
我想我会做类似的事情,将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)
))
)
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>
我个人更喜欢用破坏性的方式来编写它,例如:
const makeSorter = ({direction, isNumber, column}) => R.sort (
(direction === 'descending' ? R.descend : R.ascend) ( R.compose (
isNumber ? Number.parseFloat : R.toLower,
R.prop (column)
))
)
但这并没有改变任何基本面。
答案 1 :(得分:0)
您可以将ascend
或descend
与converge
一起使用:
const arr = [{a: 10, b: 'ZZZ'}, {a: 5, b: 'ccc'}, {a: 11, b: 'aaa'}];
const makeSort = converge(call, [
({dir}) => dir === 'ascending' ? ascend : descend,
({isNumber, key}) => isNumber ? compose(parseFloat, prop(key)) : compose(toLower, prop(key))]);
const ascSortB = makeSort({dir: 'ascending', isNumber: false, key: 'b'});
const descSortA = makeSort({dir: 'descending', isNumber: true, key: 'a'});
console.log(sort(ascSortB, arr));
console.log(sort(descSortA, arr));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {sort, ascend, descend, prop, converge, call, compose, toLower} = R;</script>
您可能还会发现this post有用