我正在处理一个问题,取两个列表,例如(1,2,3)和(a,b)并返回一个列表((1,a)(1,b)(2, a)(2,b)(3,a)(3,b))仅使用地图并展平。
这个问题要求我定义一个函数如下:
def product[A](xs: List[A], ys: List[A])= {
在此函数中获取结果。我对Scala很新,我习惯了像python和java这样的语言。
我已经走到了这一步:
def product[A](xs: List[A], ys: List[A])= {
for(y <- ys){
println(xs.map(x=> (x,y)))
}
}
这将返回如下内容:
列表((1,a),(2,a),(3,a))
列表((1,b),(2,b),(3,b))
我不确定现在如何组合这些列表。在python中我会做一些事情,比如创建一个新的列表变量,将这两个列表附加到该列表,然后展平它,这样我就有一个列表。但是,我对Scala感到困惑,因为好像我不允许在函数中定义一个新变量。我如何组合这些列表并在此时展平它们?
答案 0 :(得分:2)
产品列表仅使用地图并展平
val nums = List(1, 2, 3)
val chars = List('a', 'b')
nums.map { a => chars.map { b => (a, b) } }.flatten
Scala REPL
scala> nums.map(a => chars.map(b => (a, b)))
res5: List[List[(Int, Char)]] = List(List((1, 'a'), (1, 'b')), List((2, 'a'), (2, 'b')), List((3, 'a'), (3, 'b')))
scala> nums.map(a => chars.map(b => (a, b))).flatten
res6: List[(Int, Char)] = List((1, 'a'), (1, 'b'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b'))
可以使用flatMap和地图组合构建产品列表
nums.flatMap { a => chars.map { b => (a, b) }}
也可以使用for comprehension构建产品列表
for {a <- nums; b <- chars} yield (a, b)
Scala REPL
scala> val nums = List(1, 2, 3)
val nums: List[Int] = List(1, 2, 3)
scala> val chars = List('a', 'b')
chars: List[Char] = List('a', 'b')
scala> nums.flatMap { a => chars.map { b => (a, b) }}
res2: List[(Int, Char)] = List((1, 'a'), (1, 'b'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b'))
scala> for {a <- nums; b <- chars} yield (a, b)
res3: List[(Int, Char)] = List((1, 'a'), (1, 'b'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b'))
答案 1 :(得分:1)
您可以使用进行理解来解决此问题。它实际上是map
和flatMap
的{{3}}:
def product[A](xs: List[A], ys: List[A])= {
for {
x <- xs
y <- ys
} yield {
x -> y
}
}
For-comprehensions是实现这一目标的Scala惯用方法。它更具可读性和可维护性,底层操作仍然是map
和flatMap
。实际上,即使对于不是集合但仍然具有map
和flatMap
的类型,它通常用于理解(Future
s,Option
s ,Try
等等。)
如果您想继续使用解决方案并保存列表并将其合并,则必须删除println
并添加yield
,然后展平主列表。创建:
def product[A](xs: List[A], ys: List[A]) = {
for (y <- ys) yield {
xs.map(x => (x, y))
}
}
val res = product(List(1, 2, 3), List("a", "b"))
println(res.flatten)
答案 2 :(得分:1)
val ls1 = List(1,2,3)
val ls2 = List('a','b')
def product[A](xs: List[A], ys: List[A])= xs.map(x => ys.map((x,_))).flatten
product(ls1,ls2)