过滤数组列表f#

时间:2014-08-19 16:01:47

标签: list filter f#

抱歉,如果问题基本,但我还没有能够这样做一段时间。我创建了一个列表列表,其中第二个数组包含一个可以是f或p的参数。我需要创建两个新的数组列表,一个包含具有f参数的项目,另一个包含p参数。

编辑:尝试解释自己:

我有一个包含一系列facebook出版物的列表,这些出版物中的每一个都有信息,例如它是什么类型的出版物......它们可以是p(文本)或f(图片)。我需要做的是通过类型出版物创建两个单独的出版物列表。

数据示例:[[|“publication0ID”,“Poster0ID”,“TypeofPublication0”|]; [|“publication1ID”,“Poster1ID”,“TypeofPublication1”|]]

2 个答案:

答案 0 :(得分:1)

let data = [[|"publication0ID"; "Poster0ID"; "f"|];[|"publication1ID"; "Poster1ID"; "p"|]]


let texts, pictures =
    data
    |> List.partition (List.ofArray >> function
        | _ :: _ :: "f" :: _ -> true 
        | _ :: _ :: "p" :: _ -> false 
        | _ -> failwith "neither f nor p"
    )

这将根据您称为“TypeOfPublication”的第三个“参数”拆分列表。

我更改了您的示例代码,因为您的子数组子列表只包含一个元组,并且根据您的“......”判断我认为这可能是错误的。

解释:

List.partition根据为列表中的每个元素调用的函数拆分列表。当函数返回true时,元素将被放入结果元组的第一个列表,并在false时放入第二个列表。

由于你的元素是数组也列出,因此将检查数组 list 中的第三个元素是否为“f”,这将导致数组列表将被放入texts结果,而“p”将被放入pictures

如果第三个元素既不是“f”也不是“p”,则会抛出异常。


评论更新:

如果你的子数组总是正好三个元素长,你可以使用这个版本:

let texts, pictures =
    data
    |> List.partition (function
        | [| _; _; "f" |] -> true
        | [| _; _; "p" |] -> false
        | _ -> failwith "neither f nor p or wrong array length"
    )

或者,您可以使用第一个版本,只需将List.ofArray >>放在function关键字和开始paren之间,使其显示为:List.partition (List.ofArray >> function(我也更新了上面的代码)。

答案 1 :(得分:0)

假设您的主列表属于(int, string) list list类型,那么如果您

let f = 1
let p = 1

您应该可以使用

过滤main_list
let f_items = seq {
    let! sub_list = main_list
    let! (selector, item) = sub_list
    if selector == f then
        yield item
}

同样,要获得“p”项,您可以使用selector == p

我必须带出我的F#书才能写出这段代码,我没有用过F#这么久!我在这台电脑上没有F#,所以我不知道上面的代码是否真的有效。