编写所有对的列表

时间:2012-08-03 21:11:07

标签: list scala functional-programming

我对Scala来说是全新的,因为通过Haskell进行函数式编程的经验非常有限。

我想尝试编写一个从单个输入列表构建的所有可能对的列表。例如:

val nums = List[Int](1, 2, 3, 4, 5)   // Create an input list
val pairs = composePairs(nums)        // Function I'd like to create

// pairs == List[Int, Int]((1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 1) ... etc)

我尝试在每个元素上使用zip和整个列表,希望它会在整个列表中复制一个项目。它不起作用(只匹配第一个可能的对)。我不确定如何重复一个元素(Haskell使用cycletake我相信),并且我在使用Scala上的文档时遇到了麻烦。

这让我觉得可能有更简洁,更实用的方式来获得我想要的结果。有没有人有一个好的解决方案?

3 个答案:

答案 0 :(得分:22)

这个怎么样:

val pairs = for(x <- nums; y <- nums) yield (x, y)

答案 1 :(得分:4)

对于那些不想重复的人:

val uniquePairs = for {
      (x, idxX) <- nums.zipWithIndex
      (y, idxY) <- nums.zipWithIndex
      if idxX < idxY
    } yield (x, y)

val nums = List(1,2,3,4,5)
uniquePairs: List[(Int, Int)] = List((1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5))

答案 2 :(得分:1)

这是另一个使用map并展平的版本

val pairs = nums.flatMap(x => nums.map(y => (x,y)))

List[(Int, Int)] = List((1,1), (1,2), (1,3), (1,4), (1,5), (2,1), (2,2), (2,3), (2,4), (2,5), (3,1), (3,2), (3,3), (3,4), (3,5), (4,1), (4,2), (4,3), (4,4), (4,5), (5,1), (5,2) (5,3), (5,4), (5,5))

如果您愿意,可以将其轻松包装到composePairs函数中:

def composePairs(nums: Seq[Int]) =
    nums.flatMap(x => nums.map(y => (x,y)))