2016-03-02 7 views
6

Kotlin ha array.indexOf(item) ma non riesco a capire come fare array.indexOfBy { lambda }. Non esiste? Posso find un articolo, ma non riesco a ottenere il suo indice allo stesso tempo.Kotlin ha array.indexOf ma non riesco a capire come fare array.indexOfBy {lambda}

Mi manca una funzione nello stdlib?

Posso creare una funzione con un ciclo che esegue il controllo degli elementi e restituisce quando trova il target. Come questo:

fun <T : Any> indexOfBy(items: Array<T>, predicate: (T) -> Boolean): Int { 
    for (i in items.indices) { // or (i in 0..items.size-1) 
     if (predicate(items[i])) { 
      return i 
     } 
    } 
    return -1 
} 

poi ho cercato di renderlo un po 'più funzionale utilizzando forEach:

fun <T : Any> indexOfBy(items: Array<T>, predicate: (T) -> Boolean): Int { 
    (items.indices).forEach { 
     if (predicate(items[it])) { 
      return it 
     } 
    } 
    return -1 
} 

o posso fare qualcosa di stupido come questo, che non è molto performante:

val slowAndSilly = people.indexOf(people.find { it.name == "David" }) 

E quello che sembra migliore è forse come funzioni di estensione:

fun <T: Any> Array<T>.indexOfBy(predicate: (T)->Boolean): Int = 
     this.withIndex().find { predicate(it.value) }?.index ?: -1 
fun <T: Any> Collection<T>.indexOfBy(predicate: (T)->Boolean): Int = 
     this.withIndex().find { predicate(it.value) }?.index ?: -1 
fun <T: Any> Sequence<T>.indexOfBy(predicate: (T)->Boolean): Int = 
     this.withIndex().find { predicate(it.value) }?.index ?: -1 

Esiste un modo più elegante e idiomatico per realizzare questo?!? Inoltre, non vedo una funzione come questa per elenchi, raccolte o sequenze.

(questa domanda è derivato dal comment on another post)

risposta

12

È possibile utilizzare indexOfFirst

arrayOf(1, 2, 3).indexOfFirst { it == 2 } // returns 1 
arrayOf(4, 5, 6).indexOfFirst { it < 3 } // returns -1 
-1

alternative che sono a portata di mano, in alcuni casi:

a.indices.first { a[it] == 2 } // throws NoSuchElementException if not found 
a.indices.find { a[it] == 2 } // null if not found 
Problemi correlati