好的,这里有几个小问题。然而,调试一个大问题通常比调试几个小问题更容易。
使用
ifElse
正确地
第一个是使用
如果其他
。这将三个函数作为参数,并返回一个新函数,该函数根据使用参数调用第一个函数的结果,
呼叫
具有这些参数的第二个或第三个函数。请注意,它不会返回函数;它叫它。有几种方法可以解决此问题。您可以将这些函数包装为
always
:
const sortDirection = R.ifElse(R.equals('DESC'), always(descend), always(ascend))
但我认为放弃point free和使用
const sortDirection = dir => (dir === 'DESC' ? descend : ascend)
理解力
compose
其次,您将一个稍有错误的值传递到
ascend
或
descend
.虽然这还不是很好的实现,但想想
上升
就像
const ascend = curry(fn, a, b) => fn(a) < fn(b) ? -1 : fn(a) > fn(b) ? 1 : 0);
请注意,如果将一元函数传递给
fn = prop('name')
,你回去
(a, b) => fn(a) < fn(b) ? -1 : fn(a) > fn(b) ? 1 : 0
,这是一个二进制比较器函数。
sortWith
接受比较器列表。所以这很好。
但是如果你的
sortOrder
是
'ASC'
,然后这个
sortWith([ compose(sortDirection(sortOrder), prop('name')), ])
成为
sortWith([ compose(ascend, prop('name')) ])
相当于
sortWith([ x => ascend(prop('name')(x)) ])
传递给分类器的函数不是一个合适的比较器。它是一元函数。问题是
prop('name')
是一元函数,因此
组成
没有达到你的期望。
如果稍微重新排列,您可以获得正确的行为:
sortWith([ compose(sortDirection(sortOrder), prop)('name'), ], )
这将首先转换为
ASC
到
sortWith([ compose(ascend, prop)('name'), ], )
因此
sortWith([ (x => ascend(prop(x)))('name'), ], )
这是
sortWith([ ascend(prop('name')), ], )
正如我们所看到的,
ascend(fn)
是一个二进制比较器。
把它放在一起
因此,解决问题的一种方法是
const sortDirection = R.ifElse(R.equals('DESC'), always(descend), always(ascend))
const sortOrder = 'DESC'
sortWith([ compose(sortDirection(sortOrder), prop)('name'), ], data)
//=> [{.. Tim}, {.. Sadie}, {.. Asterios}, {.. Alex}]
当然如果
sortOrder = 'ASC'
然后
sortWith([ compose(sortDirection(sortOrder), prop)('name'), ], data)
//=> [{.. Alex}, {.. Asterios}, {.. Sadie}, {.. Tim}]
备用进近
对于上述内容,有两件事我仍然很不喜欢:
-
它使用自由变量
排序器
。我希望这些变量是我函数的参数。
-
它使用
sortWith公司
而不是
sort
。
sortWith公司
是一种
结合
比较器功能。因为我们只有一个,
分类
更简单。
我可以这样写来解决这些问题:
const {ascend, descend, prop, sort} = R
const data = [{ id: 2, name: 'Asterios' }, { id: 1, name: 'Alex' }, { id: 4, name: 'Tim' }, { id: 3, name: 'Sadie' }]
const sorter = dir => (dir === 'DESC' ? descend : ascend)(prop('name'))
console.log(sort(sorter('DESC'), data))
//=> [{.. Tim}, {.. Sadie}, {.. Asterios}, {.. Alex}]
console.log(sort(sorter('ASC'), data))
//=> [{.. Alex}, {.. Asterios}, {.. Sadie}, {.. Tim}]
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>