F#过滤子列表

问题描述 投票:2回答:2

这是一个输入列表:[[10;2;10]; [10;50;10]; [10;1;10]]

我如何过滤每个子列表的第二个元素?

下面是我的代码,当我输出结果我得到[[10;50;10]]但我想要的是[2;50;1]。反正有没有修复我的代码?我真的想了解F#。我在这里先向您的帮助表示感谢。

let sub =

     let input = [[10;2;10]; [10;50;10]; [10;1;10]]
     let findIndex input elem = input |> List.findIndex ((=) elem)
     let q = input |> List.filter(fun elem -> findIndex input elem = 1)
     printfn "%A" q
list filter f#
2个回答
1
投票

以下将获得预期结果:

let second (x:List<int>) = x.[1]
let q = List.map second input 

List.map是一个更高阶的函数,它通过将一个函数(第一个参数,这里是返回列表的第二个元素的函数second)应用于列表(这里是input)来创建一个新的列表:

[ [10;2;10]; [10;50;10]; [10;1;10] ]
       |          |          |
    second     second      second       <--- mapping function
       |          |          |
       V          V          V
[     2    ;     50    ;     1    ]

1
投票

使用List.map,而不是List.filter

List.filter根据您提供的功能保留/删除输入列表中的项目,例如List.filter (fun x -> x % 2 = 0) myList只保留myList中的偶数。您可以根据其类型签名(val filter: ('a -> bool) -> 'a list -> 'a list)了解此功能,这意味着它需要一个函数(接受一个'a并返回一个布尔值:('a -> bool)),然后获取一个列表,并返回一个相同类型的列表。

另一方面,List.map根据您提供的函数将列表的每个元素转换为您想要的任何元素。在你的情况下你会像这样使用它:

let input = [[10;2;10]; [10;50;10]; [10;1;10]]
let result = input |> List.map (fun numbers -> numbers.[1])
printfn "%A" result

List.map的签名是val map: ('a -> 'b) -> 'a list -> 'b list,意思是它需要一个函数将'as映射到'bs(在你的情况下,这会将int lists映射到ints),获取第一件事的列表,并返回第二件事的列表。

使用List.map和List.tryIndex

请注意,如果任何子列表太短,程序将崩溃。如果这是一个问题,你可以使用安全版本的myList.[i];即List.tryIndex,如果找不到该项,则返回None。试试这个:

// Note the last sublist
let input = [[10;2;10]; [10;50;10]; [10;1;10]; [-1]]
let result : int option list = input |> List.map (fun numbers -> List.tryIndex 1 numbers)
printfn "%A" result
// This prints:
// [Some 2; Some 50; Some 1; None]
© www.soinside.com 2019 - 2024. All rights reserved.