使用范围的稀疏值列表

时间:2016-01-19 15:45:02

标签: kotlin

是否有更简洁的写作方式

listOf('a'..'z','A'..'Z').flatMap { it }

这里的想法是迭代某个范围内的某些值,例如1到100之间的数字,跳过21到24

listOf(1..20, 25..100).flatMap { it }

2 个答案:

答案 0 :(得分:20)

使用flatten()代替flatMap(),您可以略微缩短列表:

+

或更短的表单(来自@Ilya)是使用plus() + operatorIterable范围实现的接口)。每个val validLetters = ('a'..'z') + ('A'..'Z') val someNumbers = (1..20) + (25..100) 都会复制一份清单:

Sequence

或者更加懒惰sequenceOf('a'..'z','A'..'Z').flatten() (不确定在这里是否更加懒惰):

// helper functions
fun sparseListOf(vararg ranges: CharRange): List<Char> = ranges.flatMap { it }       
fun sparseListOf(vararg ranges: IntRange): List<Int> = ranges.flatMap { it }

作为助手功能

在Kotlin中,人们通常会创建一个辅助函数来很好地包装这样的东西;如果你碰巧重复使用这段代码:

val validLetters = sparseListOf('a'..'z', 'A'..'Z')
val someNumbers = spareListOf(1..20, 25..100)

......以及这些助手的用法:

flatMap()

注意: 帮助函数使用flatten(),因为Array<out XYZ>没有vararg方法或扩展名是从{{1}}收到的类型。 lambda内联很可能没有真正的性能差异。

答案 1 :(得分:2)

kotlin.Char.rangeTo返回CharRangeCharProgressionIterable的实现。 CharProgression是Iterable<T>.plus的子类,而plus运算符是在iterables上定义的:('a'..'z') + ('A'..'Z')

Yeilding一个非常简单的外观和明显的

module Main where

fib :: Int -> Int
fib 1 = 1
fib 2 = 1
fib n = fib (n-1) + fib (n-2)

main :: IO ()
main = run >> run >> run
  where
    run = mapM_ (print . fib) [1..40]