F#过滤具有多个参数的二维数组

时间:2014-08-21 19:55:31

标签: arrays list f# filtering

我已经被这个看似基本的问题困住了一段时间。我有一个二维的字符串数组和另一个一维的字符串数组。一维阵列由二维阵列的一列中存在的一些元素组成。我希望得到的结果是二维数组,它由二维数组中的元素过滤。举个例子:

二维数组:

  

[[" A"," elephant"],[" B"," dog"],[" C& #34;," cat"],[" D","鼠标"],[" E","长颈鹿&# 34;]]

一维数组:

  

["象" ," cat" ,"长颈鹿"]

期望的结果:

  

[[" A"," elephant],[" C"," cat"],[" E" ,"长颈鹿"]]

我事先感谢你的帮助。我对F#很陌生,到现在为止一直很难学习它。

欢呼声

2 个答案:

答案 0 :(得分:3)

我们假设您有一个像这样的元组列表:

let animalList = 
    [("A", "elephant"); ("B", "dog"); ("C", "cat"); ("D", "mouse"); ("E", "giraffe")]

另一个你想要保留的动物清单,让我们在它们之前做好准备:

let animalsToKeep = 
    ["elephant"; "cat"; "giraffe"] |> Set.ofList

然后定义一个过滤元组列表的函数,只保留那些出现在给定集合中的元素

let filterWithSet set lst =
    lst 
    |> List.filter (fun (_, elem) -> Set.contains elem set)

并称之为:

filterWithSet animalsToKeep animalList

答案 1 :(得分:2)

答案取决于你真正想做的事情,但听起来找到正确的表达方式是问题中最重要的部分。在您的示例中,嵌套列表总是只包含两个值(例如" A"和" elephant"),因此使用元组列表会更有意义:

let things = [ ("A", "elephant"); ("B", "dog"); ("C", "cat");
               ("D", "mouse"); ("E", "giraffe")]

这种表示方式会使事情变得更容易,因为我们只需要检查元组的第二个元素是否在用于过滤的列表中:

let filter = ["elephant" ; "cat" ; "giraffe"]

为此,您可以使用List.filter过滤列表。在这种情况下,您可以使用snd获取动物(获取元组的第二个元素),然后使用List.exist查看它是否在要包含的动物列表中:

things |> List.filter (fun nested ->
  let animal = snd nested
  filter |> List.exists (fun a -> a = animal))

如果您想提高查询效率,可以创建一组过滤的项目:

let filter = set ["elephant" ; "cat" ; "giraffe"]
things |> Seq.filter (fun nested -> filter.Contains(snd nested))

事实上,你可以使用函数组合来调用snd,然后检查:

things |> Seq.filter (snd >> filter.Contains)

这意味着与上面的行完全相同 - 它使用带有字母和动物名称的元组,使用snd函数提取动物名称,然后将名称传递给filter.Contains以查看如果它在集合中。

相关问题