Как я могу найти результат метода первого элемента, который не является нулем? - PullRequest
0 голосов
/ 18 июня 2019

Итак, у меня есть парсеры, и я хочу использовать первое, которое возвращает ненулевое значение. Как бы я сделал это наиболее элегантно?

return parsers.map { it.parse(content) }.firstOrNull { it != null }

отобразит все (миллион?) Парсеры перед выбором первого.

return parsers.firstOrNull { it.parse(content) != null }?.parse(content)

снова запустит (дорогой?) parse().

Я знаю, что могу

for (parser in parsers) {
    val result = parser.parse(content)
    if (result != null) {
        return result
    }
}
return null
parsers.forEach { it.parse(content)?.run { return this } }
return null

- самое короткое, что я могу получить, но читать не очень приятно.

Я почти уверен, что здесь есть ярлык, которого я не вижу.

Ответы [ 3 ]

6 голосов
/ 18 июня 2019

Используйте последовательность. Это делает ваши вычисления ленивыми, так что вы будете вычислять parse столько раз, сколько вам нужно.

return parsers.asSequence()
              .map { it.parse(content) }
              .find { it != null }
4 голосов
/ 18 июня 2019

В качестве альтернативы издержкам Sequence или отображению большого количества значений без необходимости, вы можете использовать метод расширения, такой как:

inline fun <T, R> List<T>.firstMappedNotNull(transform: (T) -> R): R? {
    for (e in this)
        return transform(e) ?: continue
    return null
}

При этом используется минимум вызовов функций отображения и временныхобъекты.Он обязательно написан обязательным образом, но он достаточно короткий и делает ваш собственный код коротким, понятным и функциональным.

(Эта версия возвращает null, если список был пуст или каждое отображение вернуло nullКонечно, вы могли бы изменить подпись и последнюю строку, чтобы вместо этого выдать исключение.)

Жаль, что этой функции нет в стандартной библиотеке.Но добавить свой собственный легко!

3 голосов
/ 18 июня 2019

Также вы можете использовать следующий код:

parsers.asSequence()
    .mapNotNull { it.parse(content) }
    .firstOrNull()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...