Есть ли функция для поиска в ArrayList с позиции? - PullRequest
1 голос
/ 11 октября 2019

Я внимательно прочитал документацию ArrayList в Kotlin , и, очевидно, нет способа найти значение в ArrayList, начиная с указателя. Альтернатива - написать свою собственную функцию, повторяя правильные элементы в ArrayList и проверяя условие.

Итак, я запрограммировал следующий код:

fun <T> ArrayList<T>.findNext(cond: (T) -> Boolean, p: Int = 0): Int {
    for (i in p..this.lastIndex) 
        if (cond(this[i]))  return i
    return -1
}    

data class Person (
    var name: String,
    var age: Int
)


fun main()  {
    var v = arrayListOf<Person>()
    v.add(Person("Paul", 22))
    v.add(Person("Laura", 24))
    v.add(Person("Paul", 50))
    v.add(Person("Mary", 24))

    println(v.findNext({it.name=="Paul"}))    // 0
    println(v.findNext({it.name=="Paul"}, 1)) // 2
    println(v.findNext({it.name=="Paul"}, 3)) // -1
}

Есть ли что-то лучше этого?

Ответы [ 3 ]

2 голосов
/ 11 октября 2019
fun main() {
    var v = arrayListOf<Person>()
    v.add(Person("Paul", 22))
    v.add(Person("Laura", 24))
    v.add(Person("Paul", 50))
    v.add(Person("Mary", 24))

    println(v.findNext({ it.name == "Paul" },0))//IndexedValue(index=0, value=Person(name=Paul, age=22))
    println(v.findNext({ it.name == "Paul" },2))//IndexedValue(index=2, value=Person(name=Paul, age=50))
    println(v.findNext({ it.name == "Paul" },3))//null
}

private fun <T> List<T>.findNext(cond: (T) -> Boolean, position: Int): IndexedValue<T>? {

    return withIndex().filter { it.index >= position }.firstOrNull { cond(it.value) }
}
2 голосов
/ 11 октября 2019

Вы можете избежать любых промежуточных коллекций:

inline fun <T> List<T>.findNext(p: Int = 0, cond: (T) -> Boolean) = 
    listIterator(p).withIndex().asSequence().find { cond(it.value) }?.let { it.index + p }

Меняя местами аргументы, вы можете назвать это так:

println(v.findNext {it.name=="Paul"})  // 0
println(v.findNext(1) {it.name=="Paul"}) // 2
println(v.findNext(3) {it.name=="Paul"}) // null
1 голос
/ 11 октября 2019

может использовать с индексом и фильтром?

    val arrayNames = listOf<String>("Paul", "Ann", "Paul", "Roger","Peter")

    arrayNames.withIndex().filter {
        it.value == "Paul" //value contains the original name
    }.forEach{
         println(it.index) //indext contains the position.
    }

это даст вам выходные данные 0 и 2

для вашего случая (объект person вместо String), который вы будете использовать

    it.value.name == "Paul"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...