Kotlin - 数组中重复元素的索引

3
有没有一种简单的方法在不编写for循环并收集索引的情况下获取数组中匹配元素的索引?
Eg: val arr = arrayOf<Int>(2,3,4,2,5,2,6,3,2)

Output: For element 2, output should be (0,3,5,8) and For element 3, output should be (1,7)

Kotlin提供了indexOf(element)方法,它返回第一个索引,然后lastIndexOf(element)方法会给出最后一个索引。我正在寻找一种简单的方法来获取所有匹配元素的索引。

我的解决方案:迭代数组并收集索引的标准解决方案。

var indexArrOf2 = mutableListOf<Int>()
var indexArrOf3 = mutableListOf<Int>()
for(i in arr.indices) {
  if (arr[i] == 2) {
    indexArrOf2.add(i)
  }
  if (arr[i] == 3) {
    indexArrOf3.add(i)
  }
}

1
这可能一点也不高效,但你可以像这样做:arr.mapIndexed { index, value -> if (value == 2) index else null }.filterNotNull() - Michael
3个回答

9

是的,你可以使用mapIndexedNotNull

arr.mapIndexedNotNull { index, elem -> if (elem == 2) index else null }

1

有点复杂,但返回一个地图Map<Element,List<Indices>>,可根据需要使用。

arr.mapIndexed { index, i -> i to index  }   //List<Pair<Int, Int>> - [(2, 0), (3, 1), (4, 2), (2, 3), (5, 4), (2, 5), (6, 6), (3, 7), (2, 8)]
.groupBy { it.first }   //Map<Int, List<Pair<Int, Int>>> - {2=[(2, 0), (2, 3), (2, 5), (2, 8)], 3=[(3, 1), (3, 7)], 4=[(4, 2)], 5=[(5, 4)], 6=[(6, 6)]} 
.mapValues { it.value.map { it.second } }   //Map<Int, List<Int>> - {2=[0, 3, 5, 8], 3=[1, 7], 4=[2], 5=[4], 6=[6]}

0

我会使用withIndex()扩展函数来添加索引。然后,您可以选择匹配的项并获取它们的索引:

val arr = arrayOf(2, 3, 4, 2, 5, 2, 6, 3, 2)

println(arr.withIndex().filter{ it.value == 2 }.map{ it.index })
// prints '[0, 3, 5, 8]'

我认为使用filter和map会循环两次(总循环次数将是两倍),这不是理想的,甚至比原始OP的方法更不优化。我建议使用sequences,因为这只会循环一次。 - Animesh Sahu

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