Functional programming 通过查看第二个列表中的布尔值筛选一个列表中的元素

Functional programming 通过查看第二个列表中的布尔值筛选一个列表中的元素,functional-programming,sml,smlnj,Functional Programming,Sml,Smlnj,我有两张长度相等的单子。我想通过查找第一个列表中的元素(如果第二个列表中具有相同索引的元素具有真布尔值),来过滤第一个列表中的元素 Example: [1,2,3,4,5]:int list [true,false,false,true,false]:bool list Expected result: [1,4] 我知道实现这一目标的两种方法: 1) 编写一个包含两个列表的函数。对于第一个列表中我要附加的每个元素,检查第二个列表的当前(head)元素是否为true 2) 压缩这两个列表

我有两张长度相等的单子。我想通过查找第一个列表中的元素(如果第二个列表中具有相同索引的元素具有真布尔值),来过滤第一个列表中的元素

Example:

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

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

Expected result: [1,4]
我知道实现这一目标的两种方法:

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

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


应该有一个更简单的方法,对吧?

不太好。最干净的方法可能是

List.map (fn (x,y) => x) (List.filter (fn (x,y) => y) (ListPair.zip (L1,L2)))
ListPair.foldr (fn (x,y,z) => if y then x :: z else z) [] (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)

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

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

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

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

[x |(x,True)最简单的可能是

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

查看我对
List.mappointal
的使用,查看
map valOf
@SimonShine太糟糕了,因为在这样的地方它会发光。没关系!