【问题标题】:Filtering elements of one list by looking at boolean values from the second list通过查看第二个列表中的布尔值来过滤一个列表的元素
【发布时间】:2013-12-19 05:55:52
【问题描述】:

我有两个长度相等的列表。我想通过查看第二个列表中具有相同索引的元素是否具有真正的布尔值来过滤第一个列表的元素。

Example:

[1,2,3,4,5]:int list

[true,false,false,true,false]:bool list

Expected result: [1,4]

我知道有两种方法可以实现这一目标:

1) 编写一个接受两个列表的函数。对于我要附加的第一个列表中的每个元素,检查第二个列表的当前(头)元素是否为真。

2) 压缩两个列表,根据布尔值过滤。

这应该更容易解决,对吧?

【问题讨论】:

    标签: functional-programming sml smlnj


    【解决方案1】:

    最简单的大概是

    ListPair.foldr (fn (x,y,z) => if y then x :: z else z) [] (L1, L2)
    

    【讨论】:

      【解决方案2】:

      不知道 ML 是否有列表理解,但如果你的语言有它:

      [ x | (x, True) <- zip xs ys ]
      

      【讨论】:

      • @SimonShine 太糟糕了,因为在这种情况下它会发光。没关系!
      【解决方案3】:

      这几乎是您拥有的两个选项;要么一次递归两个列表,要么将它们组合成一个元组列表并递归。您可以使用多种组合器来实现后者。

      val foo = [1,2,3,4,5];
      val bar = [true,false,true,true,false];
      val pairs = ListPair.zip (foo, bar)
      

      压缩后,您可以通过以下两种方式进行压缩:

      val result = List.foldr (fn ((n,b), res) => if b then n::res else res) [] pairs
      val result = List.mapPartial (fn (n,b) => if b then SOME n else NONE) pairs
      

      【讨论】:

        【解决方案4】:

        不是真的。最干净的方法可能是

        List.map (fn (x,y) => x) (List.filter (fn (x,y) => y) (ListPair.zip (L1,L2)))
        

        List.map Option.valOf (List.filter Option.isSome (ListPair.map(fn (x,y) => if y then SOME x else NONE) (L1,L2)))
        

        递归函数也不错:

        fun foo ([],[]) = []
          | foo ([],L) = raise Fail "Different lengths"
          | foo (L,[]) = raise Fail "Different lengths"
          | foo (x::xs, b::bs) = if b then x::foo(xs,bs) else foo(xs,bs)
        

        【讨论】:

        • 查看我对List.mapPartial 的使用,而不是map valOf
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-03
        • 1970-01-01
        • 2017-12-16
        • 2017-10-15
        • 2012-08-07
        相关资源
        最近更新 更多