В Котлине, как проверить содержит то или иное значение?
в Котлине мы можем сделать:
val arr = intArrayOf(1,2,3)
if (2 in arr)
println("in list")
но если я хочу проверить, если 2 или 3 в arr
, каков самый идиоматический способ сделать это, кроме:
if (2 in arr || 3 in arr)
println("in list")
6 ответов
Я хотел бы использовать any () метод расширения:
arrayOf(1, 2, 3).any { it == 2 || it == 3 }
таким образом, вы пересекаете массив только один раз, и вы не создаете экземпляр set только для того, чтобы проверить, пуст он или нет (как в одном из других ответов на этот вопрос).
можно использовать пересечение метод, он принимает iterable как paramter и возвращает набор, содержащий только элементы, которые находятся как в вашей коллекции, так и в iterable вы предоставили. Тогда на этом наборе вам просто нужно сделать проверку размера.
вот пример:
val array1 = arrayOf(1, 2, 3, 4, 5, 6)
val array2 = arrayOf(2, 5)
// true if array1 contains any of the items from array2
if(array1.intersect(array2.asIterable()).isNotEmpty()) {
println("in list")
}
это самый короткий и самый идиоматический способ, который я могу придумать, используя any
и in
:
val values = setOf(2, 3)
val array = intArrayOf(1, 2, 3)
array.any { it in values }
конечно, вы можете использовать ссылка на функцию для in оператор как это:
array.any(values::contains)
Я использую setOf
для первой коллекции, потому что порядок не имеет значения.
Edit: я перешел values
и array
из-за Алекс.dorokhow ответ. Порядок не имеет значения для проверки но для производительности.
ОП хотел самый идиоматический способ решения этой проблемы. Если вы после более эффективного способа пойти на ада.
объединение решений @aga и @willi-mentzel для повышения эффективности и динамического набора проверенных значений:
val numbers = setOf(2, 3)
arrayOf(1, 2, 3).any(numbers::contains)
в этом случае массив будет повторяться полностью только один раз (в худшем случае не более).
это более эффективно, чем (предложено @WilliMentzel):
numbers.any(arrayOf(1, 2, 3)::contains) // don't do that!
где массив будет повторяться set.граф!--10--> раз в худшем случае.
отметим, что Set.содержит имеет O (1) сложность, но IntArray:: содержит имеет O (N).
конечно, эта оптимизация имеет смысл только если набор или массив достаточно большой.
Я думаю, что наиболее читабельно написать заявление наоборот:
val arr = intArrayOf(1,2,3)
val match = setOf(2, 3).any(arr::contains)
возможно даже использовать диапазоны в определенных сценариях:
val match = (2..3).any(arr::contains)
В конце концов, ваше решение выглядит довольно хорошо для меня уже. Хотя и не используя функциональность fancy library.
Если это не имеет значения, если оба происходят в массиве, вы можете использовать when
такое выражение:
when (arr) {
2,3 --> println("in list")
else --> println("not in list")
}
это будет печатать "в списке", когда 2 или 3 находятся в списке.
дополнительные сведения об управлении потоком см. В разделе здесь