我下面有一个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中有什么方法可以做到这一点吗? 非常感谢
答案 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))