<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 1. 前言 為了了解什么是`DSL`,這里我百度了一下: > `DSL`(`domain specific language`),即**領域特定語言**,是編程的一種范式。專門解決某一特定問題的計算機語言,比如大家耳熟能詳的 `SQL` 和正則表達式。`DSL` 只專注于某個領域,比如 `SQL` 僅支持數據庫的相關處理,而正則表達式只用來檢索和替換文本,我們無法用 `SQL` 或者正則表達式來開發一個完整的應用。DSL 往往具備**獨特的代碼結構和一致的代碼風格**。 以上內容摘自:[Kotlin之美——DSL篇 - 簡書 (jianshu.com)](https://www.jianshu.com/p/f5f0d38e3e44) # 2. 簡單使用DSL ## 2.1 變換 變換是函數式編程的第一大類函數,會遍歷集合內容,以值參形式傳入的變換器函數,變換每一個元素,然后返回修改后元素。通常使用的函數為`map`和`flatMap`。 ### 2.1.1 map ~~~ fun main() { var users = listOf("張三", "李四", "王五") // 使用map進行變換 val maped = users.map { it -> "我是$it" } println(users) println(maped) } ~~~ 結果: ``` [張三, 李四, 王五] [我是張三, 我是李四, 我是王五] ``` 類似的,這里也可以為`flatMap`來做一個簡單的案例。 ### 2.1.2 flatMap 這個函數可以將多個集合合并,返回一個集合。 ~~~ fun main() { var users = listOf( listOf("張三", "張思"), listOf("李四", "李六") ) // 合并集合的集合 val flatMap = users.flatMap { it } println(flatMap) } ~~~ 結果: ``` [張三, 張思, 李四, 李六] ``` ## 2.2 過濾 過濾函數接收一個斷言函數,按照條件給出`true`或者`false`,如果按照條件判斷為`true`就留在集合,否則被移除。需要注意的是,這里的保留或者移除還是在副本中進行,不修改原本集合。 ### 2.2.1 filter ~~~ fun main() { var users = listOf("張三", "李四", "王五", "趙六") val filteredUsers = users.filter { it.contains("王") } println(users) println(filteredUsers) } ~~~ 結果: ``` [張三, 李四, 王五, 趙六] [王五] ``` 再比如我們需要在一堆數據中找素數: ~~~ fun main() { var datas = listOf( listOf(1, 4, 5, 6, 7, 20), listOf(3, 5, 7, 9, 0, 13) ) // 找datas中的素數 val filter = datas.flatMap { it }.filter { data -> (2 until data).map { data % it } .none { it == 0 } // Returns `true` if no elements match the given [predicate]. } println(filter) } ~~~ 結果: ``` [1, 5, 7, 3, 5, 7, 0, 13] ``` 注意到`(2 until data)`返回的為`[2, ..., data-1]`。由于`filter`的斷言函數為`true`或者`false`,這里需要使用`none`來逐個元素判斷是否滿足斷言條件。觀看其源碼,可以將其寫為下面的函數: ~~~ // 等價寫法 fun judgement(data: Int): Boolean{ var list: MutableList<Int> = mutableListOf() for (i in 2 until data){ list.add(data % i) } // none for (element in list) { // 如果能夠被2到data-1的任意一個數整除,表示不是素數 if (element == 0) return false } return true } val filter1 = datas.flatMap { it }.filter { data -> judgement(data) } println(filter1) ~~~ 結果: ``` [1, 5, 7, 3, 5, 7, 0, 13] ``` 這里再摘抄一下`none`的源代碼: ~~~ /** * Returns `true` if no elements match the given [predicate]. * * @sample samples.collections.Collections.Aggregates.noneWithPredicate */ public inline fun <T> Iterable<T>.none(predicate: (T) -> Boolean): Boolean { if (this is Collection && isEmpty()) return true for (element in this) if (predicate(element)) return false return true } ~~~ 當然,有些時候我們需要的是取`topk`個元素,所以這里可以使用`take`函數: ~~~ // 判斷一個數是否是素數 【擴展函數】 fun Int.isPrime(): Boolean { (2 until this).map { if(this % it == 0) return false } return true } fun main() { var datas = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) // 找datas中的素數,并取前3個 val take = datas.filter { data -> data.isPrime() }.take(3) println(take) } ~~~ 結果: ``` [1, 2, 3] ``` ## 2.3 映射合并 ### 2.3.1 zip 也就是使用`zip`函數,進行`key-value`的兩個集合的合并。比如下面的案例: ~~~ fun main() { var keys = listOf("zs", "ls", "ww") var users = listOf("張三", "李四", "王五") val zip = keys.zip(users) println(zip) } ~~~ 結果: ``` [(zs, 張三), (ls, 李四), (ww, 王五)] ``` 從上面結果中可以看出,結果為二元組的列表。有時候我們所期望的是一個`Map`集合,所以,我們可以進一步進行處理: ~~~ val zip = keys.zip(users).toMap() ~~~ 結果: ~~~ {zs=張三, ls=李四, ww=王五} ~~~ 不妨來看一下`zip`的源碼: ~~~ public infix fun <T, R> Iterable<T>.zip(other: Iterable<R>): List<Pair<T, R>> { return zip(other) { t1, t2 -> t1 to t2 } } ~~~ 可以簡單解讀下,首先回顧一下`infix`關鍵字: > 當定義的擴展函數只有一個參數,可以使用`infix`來進行簡化,如果定義函數的時候使用了這個關鍵字,那么點操作符以及參數的括號都可以不要。 - 使用`infix`關鍵字,可以支持在調用的時候不要點操作符以及參數的括號; - 使用泛型`<T, R>`,方便支持各種類型; - 傳入一個列表,返回一個列表對,類型為`<T, R>`,即:調用列表元素類型和傳入參數元素類型; ### 2.3.2 fold 接收一個初始累加器的值,然后根據傳入的函數進行值的更新,最后進行累加。 ~~~ fun main() { var datas = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val fold = datas.fold(10) { accumulator, element -> accumulator + element } println(fold) } ~~~ 結果: ``` 65 ``` 其實看`fold`的源碼也可以知道其原理: ~~~ public inline fun <T, R> Iterable<T>.fold(initial: R, operation: (acc: R, T) -> R): R { var accumulator = initial for (element in this) accumulator = operation(accumulator, element) return accumulator } ~~~ 其實也就是`for`循環來完成的操作。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看