Is there a convention for getting all indices of a...
# codingconventions
z
Is there a convention for getting all indices of a value in an array? I came up with this for ByteArrays, but wanted to make sure I wasn't missing a library method by an unfamiliar name
Copy code
inline fun ByteArray.indicesOf(value: Byte): List<Int> =
    mapIndexed { index, byte -> index.takeIf { byte == value } }.filterNotNull()
I have an alternate implementation of this that folds over a mutable list, but this ended up looking cleaner.
e
there is
mapIndexedNotNull
z
Hmm, is that on the JVM side? In a Multiplatform project I don't seem to have access to that, I'll check the docs
Ah, it only applies to Array<out T>
Ends up looking like
Copy code
toTypedArray().mapIndexedNotNull { index, byte -> index.takeIf { byte == value } }
e
ah there's no overload for primitive arrays… oh well
even though it's longer, I'd find
Copy code
inline fun ByteArray.indicesOf(value: Byte): List<Int> = buildList {
    for ((index, byte) in this@indicesOf.withIndex()) {
        if (byte == value) add(index)
    }
}
to be clearer
1
y
I'd personally use
forEachIndexed
there just because it doesn't allocate the IndexedValue, but it really doesn't matter
1
k
Another possibility:
Copy code
fun ByteArray.indicesOf(value: Byte): List<Int> =
    withIndex().mapNotNull { (index, byte) -> index.takeIf { byte == value } }
This is as short as the above solutions that use
mapIndexed
and
mapIndexedNotNull
but it doesn't create an intermediate list, since
withIndex
returns a lazy iterator. Also, the following doesn't create any copies of the data, but just a list wrapping the original array:
Copy code
asList().mapIndexedNotNull { index, byte -> index.takeIf { byte == value } }
which is exactly like your solution that uses
toTypedArray
but without copying the data.
e
because it doesn't allocate the IndexedValue
for (.withIndex())
is intrinsified so it doesn't either, https://youtrack.jetbrains.com/issue/KT-5177/Optimize-code-generation-for-for-loop-with-withIndex
👀 1
thank you color 2
k
That's good to know. It would have been better if this was mentioned in the Javadoc of
withIndex
, since that's where developers would look if they wanted to know more about it, rather than checking old feature requests on YouTrack.
e
blob shrug it's a feature of the compiler and not the standard library, other optimizations aren't mentioned in the docs either. ideally it shouldn't change how you write code, you do the most readable thing and it should turn into something that runs decently