通过查看第二个列表中的布尔值来过滤一个列表的元素

时间:2013-12-03 08:58:45

标签: functional-programming sml smlnj

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

Example:

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

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

Expected result: [1,4]

我知道有两种方法可以做到这一点:

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

2)压缩两个列表并根据布尔值对其进行过滤。

应该更容易解决这个问题吧?

4 个答案:

答案 0 :(得分:3)

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

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)

答案 1 :(得分:2)

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

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

答案 2 :(得分:0)

最简单的可能是

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

答案 3 :(得分:-1)

不知道ML是否具有列表理解能力,但如果您的语言具有此列表:

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