F# - 使用List.foldBack将整数列表拆分为赔率和平均值

时间:2017-10-07 15:01:59

标签: list f#

我正在尝试使用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. - foldfoldBackfindfiltermapmap2 ,但如果可能的话,我更愿意看到仅使用foldBack的解决方案。

1 个答案:

答案 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而无法推断%,所以这里没有任何区别。