Так как все, что вы проверяете на это существование, вы можете просто составить 2 использования exists
:
(0 until x).exists(i => (i + 1 until x).exists(fn(i, _)))
в целом, если вы обеспокоены больше, чем просто определение, если некоторый элемент существует, вы можете конвертировать ваши понимание в серии Streams
, Iterators
или views
, вы можете использовать exists
и он будет оценивать лениво, избегая ненужных выполнений цикла:
def foo(x: Int, fn: (Int, Int) => Boolean): Boolean = {
(for {
i <- (0 until x).iterator
j <- (i + 1 until x).iterator
} yield(i, j)).exists(fn.tupled)
}
Вы также можете использовать map
и flatMap
вместо for
и toStream
или view
вместо iterator
:
(0 until x).view.flatMap(i => (i + 1 until x).toStream.map(j => i -> j)).exists(fn.tupled)
Вы также можете использовать view
в любой коллекции, чтобы получить коллекцию, где все трансформаторы выполняются лениво. Это, возможно, самый идиоматический способ короткого замыкания обхода коллекции. От the docs on views
:
Scala коллекция по умолчанию строгого во всех своих трансформаторах, за исключением Stream
, который реализует все свои методы трансформаторных лениво. Тем не менее, существует систематический способ превратить каждую коллекцию в ленивую и наоборот, которая основана на коллекции просмотров. Вид представляет собой особый вид коллекции, который представляет собой базовую коллекцию, но лениво реализует все трансформаторы.
Что касается накладных расходов, это действительно зависит от особенностей! Различные коллекции имеют разные варианты: view
, toStream
и iterator
, которые могут варьироваться в зависимости от объема накладных расходов. Если fn
очень дорого вычислять, это накладные расходы, вероятно, стоит того, и сохранение вашего идиоматического функционального стиля для вашего кода делает его более удобным для обслуживания, отлаживаемым и читаемым. Если вы находитесь в ситуации, которая требует экстремальной оптимизации, вы можете вернуться к конструкциям нижнего уровня, таким как return
(что не лишено собственных накладных расходов!).
Вы можете взглянуть на хвостовую рекурсию – cchantep