Scala对使用地图并展平

时间:2016-09-24 09:41:56

标签: list scala mapping flatten

我正在处理一个问题,取两个列表,例如(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感到困惑,因为好像我不允许在函数中定义一个新变量。我如何组合这些列表并在此时展平它们?

3 个答案:

答案 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)

您可以使用进行理解来解决此问题。它实际上是mapflatMap的{​​{3}}:

def product[A](xs: List[A], ys: List[A])= {
    for {
      x <- xs
      y <- ys
    } yield {
      x -> y
    }
}

For-comprehensions是实现这一目标的Scala惯用方法。它更具可读性和可维护性,底层操作仍然是mapflatMap。实际上,即使对于不是集合但仍然具有mapflatMap的类型,它通常用于理解(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)