我正在尝试使用List.foldBack
编写一个函数,它将整数列表拆分为一个包含两个列表的元组:一个包含几率,另一个包含原始列表的平均值。例如:
给定列表myList = [1;4;2;6;5;3;10]
,函数应该返回元组([4;2;6;10], [1;5;3])
。
我找到了很多解决方案,可以通过索引将列表拆分为子列表,但是正如所解释的那样,我需要按元素值而不是索引来拆分列表。
所以我想我会用List.foldBack
编写一个函数,它会按索引分割,然后重写它以按值拆分,但还没有成功......这就是我到目前为止所得到的:
let oddEvenSplit (listToSplit:int list) =
List.foldBack (fun x (even, odd) -> x::odd, even) listToSplit ([], [])
正如您可能已经猜到的那样,通过我的函数运行myList
会返回([1;2;5;10], [4;6;3])
。
我仅限于使用List.
- fold
,foldBack
,find
,filter
,map
和map2
,但如果可能的话,我更愿意看到仅使用foldBack
的解决方案。
答案 0 :(得分:3)
您的代码实际上并未检查该值是奇数还是偶数 - 它只是将其添加到“赔率”列表中,并交换每个值的“赔率”和“均衡”列表。如果丑陋的话,修复两者都很简单:
let oddEvenSplit listToSplit =
List.foldBack
(fun x (even, odd) -> if x % 2 = 0 then (x::even, odd) else (even, x::odd))
listToSplit
([], [])
如何使事情变得不那么丑陋是主观的,但这里有几个选择:
let oddEvenSplit listToSplit =
let impl x (even, odd) = if x % 2 = 0 then (x::even, odd) else (even, x::odd)
List.foldBack impl listToSplit ([], [])
// or
let oddEvenSplit listToSplit =
(listToSplit, ([], [])) ||> List.foldBack (fun x (even, odd) ->
if x % 2 = 0 then (x::even, odd) else (even, x::odd))
就我个人而言,我建议使用后者,因为它通常会在类型推断方面发挥得更好(因为使用int
而无法推断%
,所以这里没有任何区别。