<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國際加速解決方案。 廣告
                ### 扁平化——處理嵌套集合:flatMap、flatten #### flatten 有些時候,我們遇到的集合元素不僅僅是數值、類、字符串這種類型,也可能是集合。(緊接著filter函數章節的person數據類)比如: ``` val list = listOf(listOf(jilen, shaw, lisa), listOf(yison, pan), listOf(jack)) ``` 上面就是一個嵌套集合。這種集合我們在業務中會經常碰到,但是大多數時候,我們**都希望嵌套集合中各個元素能夠被拿出來,然后組成一個只有這些元素的集合**,就像這樣: ``` val newList = listOf(jilen, shaw, lisa, yison, pan, jack) ``` 那么我們怎樣根據嵌套集合來獲得這樣一個集合呢?Kotlin又提供給我們了一個非常棒的API—flatten。 ``` >>> list.flatten() [PersonData(name=Jilen, age=30, sex=m, score=85), PersonData(name=Shaw, age=18, sex=m, score=90), PersonData(name=Lisa, age=25, sex=f, score=88), PersonData(name=Yison, age=40, sex=f, score=59), PersonData(name=Pan, age=36, sex=f, score=55), PersonData(name=Jack, age=30, sex=m, score=70)] ``` 通過**使用flatten,我們就實現了對嵌套集合的扁平化**。其實flatten方法的原理很簡單,我們來看看它的實現源碼: ~~~ public fun <T> Iterable<Iterable<T>>.flatten(): List<T> { val result = ArrayList<T>() for (element in this) { result.addAll(element) } return result } ~~~ **首先聲明一個數組result,該數組的長度是嵌套集合中所有子集合的長度之和。然后遍歷這個嵌套集合,將每一個子集合中的元素通過addAll方法添加到result中。最終就得到了一個扁平化的集合**。 #### flatMap 假如我們**并不是想直接得到一個扁平化之后的集合,而是希望將子集合中的元素“加工”一下,然后返回一個“加工”之后的集合。比如我們要得到一個由姓名組成的列表**,應該如何去做呢?Kotlin還給我們提供了一個方法——flatMap,可以用它實現這個需求: ``` >>> list.flatMap {it.map{it.name}} [Jilen, Shaw, Lisa, Yison, Pan, Jack] ``` flatMap接收了一個函數,該函數的返回值是一個列表,一個由學生姓名組成的列表。我們先不解釋flatMap是如何工作的,先來看看能不能利用其他方法也實現上面的需求。之前我們學習過flatten方法和map方法,將這兩個方法結合起來使用一下: ``` >>> list.flatten().map {it.name} [Jilen, Shaw, Lisa, Yison, Pan, Jack] ``` 通過這個例子你會發現,**flatMap好像就是先將列表進行flatten操作然后再進行map操作,而且上面這種方式似乎比使用flatMap要更加直觀一些**。讓我們帶著疑惑進入接下來的這個場景: ``` data class Student (val name: String, val age: Int, val sex: String, val score: Int, val hobbies: List<String>) ``` 我們給學生類加了一個屬性:hobbies,用來表示學生的興趣愛好。一個學生的愛好可能有許多種: ``` val jilen = Student("Jilen", 30, "m", 85, listOf("coding", "reading")) val shaw = Student("Shaw", 18, "m", 90, listOf("drinking", "fishing")) val yison = Student("Yison", 40, "f", 59, listOf("running", "game")) val jack = Student("Jack", 30, "m", 70, listOf("drawing")) val lisa = Student("Lisa", 25, "f", 88, listOf("writing")) val pan = Student("Pan", 36, "f", 55, listOf("dancing")) val students = listOf(jilen, shaw, yison, jack, lisa, pan) ``` 那現在需要從學生列表中取出學生的愛好,然后將這些愛好組成一個列表。先看看使用flatten和map怎么去做: ``` >>> students.map {it.hobbies}.flatten() [coding, reading, drinking, fishing, running, game, drawing, writing, dancing] ``` 然后使用flatMap實現: ``` >>> students.flatMap {it.hobbies} [coding, reading, drinking, fishing, running, game, drawing, writing, dancing] ``` 通過這個例子我們又發現,**flatMap是先將列表進行map操作然后再進行flatten操作的,而且這個例子中使用flatMap要更加簡潔**。 flatMap 函數做了兩件事情:首先根據作為實參給定的函數對集合中的每個元素做變換(或者說映射),然后把多個列表合并(或者說平鋪〉成一個列表,下面通過另一個例子更加直觀地了解 ``` fun main(args: Array<String>) { val strings = listOf("abc", "def") println(strings.flatMap { it.toList() })//[a, b, c, d, e, f] } ``` ![](https://img.kancloud.cn/e3/39/e3395f000b564e65118b28a82b98595a_378x279.png) 字符串上的toList 函數把它轉換成字符列表。如果和toList一起使用的是map 函數,你會得到一個字符列表的列表,就如同圖中的第二行。flatMap 函數還會執行后面的步驟,并返回一個包含所有元素(字符)的列表。 #### flatMap源碼 那么flatMap究竟是如何工作的呢,同樣來看看它的實現源碼: ~~~ public inline fun <T, R> Iterable<T>.flatMap(transform: (T) -> Iterable<R>): List<R> { return flatMapTo(ArrayList<R>(), transform) } ~~~ 可以看到,flatMap接收一個函數:transform。 ``` transform: (T) -> Iterable<R> ``` **transform函數接收一個參數(該參數一般為嵌套列表中的某個子列表),返回值為一個列表**。比如我們前面用flatMap獲取愛好列表時: ``` { it.hobbies } // 上面的表達式等價于: { it -> it.hobbies } ``` 在flatMap中調用了一個叫作flatMapTo的方法,該方法就是實現flatMap的主要方法。該方法的源碼如下: ~~~ public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.flatMapTo(destination: C, transform: (T) -> Iterable<R>): C { for (element in this) { val list = transform(element) destination.addAll(list) } return destination } ~~~ flatMapTo接收兩個參數,一個參數為一個列表,該列表為一個空的列表,另外一個參數為一個函數,該函數的返回值為一個序列。**flatMapTo的實現很簡單,首先遍歷集合中的元素,然后將每個元素傳入函數transform中得到一個列表,然后將這個列表中的所有元素添加到空列表destination中,這樣最終就得到了一個經過transform函數處理過的扁平化列表**。 **flatMap其實可以看作由flatten和map進行組合之后的方法,組合方式根據具體情況來定。當我們僅僅需要對一個集合進行扁平化操作的時候,使用flatten就可以了;如果需要對其中的元素進行一些“加工”,那我們可以考慮使用flatMap**。
                  <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>

                              哎呀哎呀视频在线观看