【问题标题】:F# filter a two-dimensional array with multiple argumentsF#过滤具有多个参数的二维数组
【发布时间】:2014-08-22 04:37:07
【问题描述】:

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

二维数组:

[["A", "elephant"], ["B", "dog"] , ["C", "cat"] , ["D", "mouse"], ["E", "长颈鹿"]]

一维数组:

[“大象”、“猫”、“长颈鹿”]

想要的结果:

[[“A”、“大象”、[“C”、“猫”]、[“E”、“长颈鹿”]]

我提前感谢您的帮助。我对 F# 很陌生,直到现在尝试学习它一直很困难。

干杯

【问题讨论】:

  • 和你的,;s 对吧?如果没有,你会得到很多包含元组的单元素列表......
  • 这些不是数组;它们是列表。你的二维数组是一个列表列表。
  • 使用逗号而不是分号是初学者的典型错误之一,我想我们中的大多数人都在某种程度上做到了这一点。出于某种原因,您实际上是否有嵌套数组,或者您是否可以随意表示该数据?嵌套数组不是 F# 中的首选,您真的希望它是一个元组列表。
  • Daniel:嗯,它实际上是一个包含单个元组的列表,不是吗 - 我知道我们可能认为这是伪代码。
  • 我实际上对是否使用元组、数组、列表等没有任何限制。只是这样写是为了让我的问题清楚。我现在正在尝试通过 Seq.map,但到目前为止还没有成功。谢谢大家的回复!

标签: arrays list f# filtering


【解决方案1】:

假设你有一个这样的元组列表:

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

【讨论】:

    【解决方案2】:

    答案取决于您实际想要做什么,但听起来找到正确的表示是问题中最重要的部分。在您的示例中,您的嵌套列表始终只包含两个值(例如“A”和“大象”),因此使用元组列表更有意义:

    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 以查看它是否在集合。

    【讨论】:

    • 也很有效!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 2014-02-14
    • 2013-06-23
    • 1970-01-01
    • 2018-11-03
    相关资源
    最近更新 更多