3

Is there an easy way to get the index of matching elements in an array without writing a for loop and then collecting the index?

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 provides indexOf(element) which returns first index and then lastIndexOf(element) which will give me last index. Am looking for an easy way to get indexes of all matching elements.

My solution: Standard solution of iterating over the array and collecting index.

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
  • 1
    This may not be efficient at all, but you could do something like this: arr.mapIndexed { index, value -> if (value == 2) index else null }.filterNotNull() Commented Apr 5, 2020 at 8:03

3 Answers 3

9

Yes, you can use mapIndexedNotNull:

arr.mapIndexedNotNull { index, elem -> if (elem == 2) index else null }
Sign up to request clarification or add additional context in comments.

Comments

1

A little convoluted but returns a map Map<Element, List<Indices>> to use as desired.

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]}

Comments

0

I'd use the withIndex() extension function to add the index.  You can then select the matching items, and get their indices:

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]'

1 Comment

I think filter and map will loop (total loop will be twice), this is not ideal its even less optimized than original OP's approach i'd suggest using sequences as this will loop through only one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.