如何在scala列表中获取重复对的索引

时间:2018-08-09 05:00:39

标签: scala

我下面有一个scala列表:

slist = List("a","b","c","a","d","c","a")

我想在此列表中获得相同元素对的索引。 例如,此列表的结果为

(0,3),(0,6),(3,6),(2,5)

其中(0,3)表示slist(0)==slist(3) (0,6)表示slist(0)==slist(6) 等等。

那么在scala中有什么方法可以做到这一点吗? 非常感谢

3 个答案:

答案 0 :(得分:1)

有更简单的方法,但是以zipWithIndex开头就是这条路。 zipWithIndex返回带有索引和字母之一的Tuple2。从那里我们groupBy来获得字母与其索引的映射,并过滤具有多个值的索引。最后,我们有这个MapLike.DefaultValuesIterable(List((a,0), (a,3), (a,6)), List((c,2), (c,5))) ,我们从中获取索引并制成combinations

scala> slist.zipWithIndex.groupBy(zipped => zipped._1).filter(t => t._2.size > 1).values.flatMap(xs => xs.map(t => t._2).combinations(2))
res40: Iterable[List[Int]] = List(List(0, 3), List(0, 6), List(3, 6), List(2, 5))

答案 1 :(得分:1)

List编制索引效率很低,因此我建议过渡到Vector,然后再返回(如果需要)。

val svec = slist.toVector
svec.indices
    .map(x => (x,svec.indexOf(svec(x),x+1)))
    .filter(_._2 > 0)
    .toList
//res0: List[(Int, Int)] = List((0,3), (2,5), (3,6))

答案 2 :(得分:1)

 val v = slist.toVector; val s = v.size
 for(i<-0 to s-1;j<-0 to s-1;if(i<j && v(i)==v(j))) yield (i,j)

在Scala REPL中:

scala> for(i<-0 to s-1;j<-0 to s-1;if(i<j && v(i)==v(j))) yield (i,j)
res34: scala.collection.immutable.IndexedSeq[(Int, Int)] = Vector((0,3), (0,6), (2,5), (3,6))