如何将Scala列表转换为对?

36

我想要将像List(1,2,3,4)这样的Scala列表拆分成一对对的形式(1,2) (2,3) (3,4),有简单的方法吗?

3个回答

81
val xs = List(1,2,3,4)
xs zip xs.tail
  // res1: List[(Int, Int)] = List((1,2), (2,3), (3,4))

正如文档所说,zip

通过将两个可迭代集合中相应的元素一一配对组合而生成一个列表。如果其中一个集合比另一个长,则忽略其余的元素。

因此,将List('a,'b,'c,'d)List('x,'y,'z)一起压缩,得到List(('a,'x), ('b,'y), ('c,'z)),并忽略第一个集合中最后一个元素'd

通过List(1,2,3,4)tail,可以看到它们是如何成对地配对在一起的,即List(2,3,4)


2
这很简短聪明,但我认为它更难理解。 - Garrett Hall
4
这是我首选的原因,因为简洁明了。点赞! - Brian
1
@Luigi:我点赞了这个答案,也比目前被接受的答案更喜欢它,但是一个解释会比“如果你认为这难以理解就笑一笑”更有帮助。 - Travis Brown
如果您愿意在 xs 为空时返回一个空列表,则使用 xs.zip(xs.drop(1)),否则您将得到一个 UnsupportedOperationException(由于在空集合上调用tail而抛出)。 - David

17

要生成一组二元组(即元组列表),请尝试以下方法

List(1,2,3,4,5).sliding(2).collect{case List(a,b) => (a,b)}.toList

4
使用 map 而不是 collect — 这将避免一次 isDefinedAt 的调用,并且如果突然原始集合不再是 List,它会抛出一个异常而不是悄悄地产生一个空结果。出于同样的原因,你应该使用模式匹配的 Seq(a,b),而不是List(a,b) - Jean-Philippe Pellet

10
List(1,2,3,4).sliding(2).map(x => (x.head, x.tail.head)).toList
res0: List[(Int, Int)] = List((1,2), (2,3), (3,4))

1
这也是我写代码时想到的答案。在我看来,比其他答案更明显和易读。 - arviman
@arviman 这是我当时想出来的。我可能试图强制使用“滑动”。回想起来,被接受的答案要好得多。 - Brian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接