Iterable<T>相關函式

Functional Programming

原本的集合不會動到,複製一份給其它函式去執行,傳回新的結果。

Iterable.map()擴展函式

擴展函式程式碼如下:

1
2
3
public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {
    return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)
}

集合元素字串長度

Iterable.map()集合擴展函式map,會傳回跟原本集合一樣大小的集合。
以下程式碼會傳回list元素的長度,傳回新的list,不會修改到原本的list。
it代表每個集合元素。

1
2
3
4
5
fun main() {
    val list = listOf<String>("Mary", "Bill", "Alex", "Ben")
    val result = list.map { it.length }
    println(result)
}
[4, 4, 4, 3]

加上前綴字串

以下程式碼為每個元素加上前綴字串,不會修改原本list,會複製一份新的lis,修改複本傳回。
傳回的list的大小跟原本的list的大小一樣。

1
2
3
4
5
6
fun main() {
    val list = listOf<String>("Mary", "Bill", "Alex", "Ben")
        .map { "Little " + it }
        .map { "Happy " + it }
    println(list)
}
[Happy Little Mary, Happy Little Bill, Happy Little Alex, Happy Little Ben]

flatMap

flat是平的意思。
以下是二維陣列,把二維陣列變成一維陣列,使用flatMap。

1
2
3
4
5
6
fun main() {
    val list = listOf(
        listOf(1, 2, 3),
        listOf(4, 5, 6)).flatMap { it }
    println(list)
}
[1, 2, 3, 4, 5, 6]

filter篩選

it是list的元素,元素中有a的字母,加到新的list中,把新的list作為傳回值傳回。

1
2
3
4
5
fun main() {
    val list = listOf<String>("Mary", "Bill", "Alex", "Ben")
        .filter { it.contains("a") }
    println(list)
}

filter擴展函式

filter擴展函式,參數是predicate Lambda,傳回值是List。

1
2
3
public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
    return filterTo(ArrayList<T>(), predicate)
}

filterTo擴展函式

1
2
3
4
5
6
7
8
9
10
public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterTo(destination: C, predicate: (T) -> Boolean): C {
	// 遍歷所有元素
    for (element in this) {
        // 若為true
        if (predicate(element)) 
            // element 加入 destination List
            destination.add(element)
    }
    return destination
}

重要的是下面這段程式

1
2
3
4
5
6
7
// 遍歷所有元素
for (element in this) {
    // 若為true
    if (predicate(element)) 
        // element 加入 destination List
        destination.add(element)
}

predicate Lambda

predicate Lambda會傳回true或false,若為true就加到傳回值List中。

1
predicate: (T) -> Boolean

number為每個元素的參數,因為參數只有一個,可以省略,用it代替number。

1
2
3
4
5
val nums = listOf(7, 5, 4, 3, 22, 11, 18)
    .filter { number ->
        true
    }
println(nums)
[7, 5, 4, 3, 22, 11, 18]

若為false,就沒有任何元素加入List。

1
2
3
4
5
val nums = listOf(7, 5, 4, 3, 22, 11, 18)
    .filter { number ->
        false
    }
println(nums)
[]

傳回二維陣列中有red的元素

以下是二維陣列,傳回一維陣列,若元素有包含red,把它加入到陣列中。

1
2
3
4
5
6
7
fun main() {
    val list = listOf(
        listOf("red apple", "black dog", "red fish"),
        listOf("yellow car", "blue sky", "blue car"))
        .flatMap { it.filter { it.contains("red") } }
    println(list)
}
[red apple, red fish]

質數

質數只能被1與自己整除。

1
2
3
4
5
6
7
8
fun main() {
    val nums = listOf(7, 5, 4, 3, 22, 11, 18)
    val prime = nums.filter { number ->
        (2 until  number).map { number % it }
            .none{ it == 0}
    }
    println(prime)
}
[7, 5, 3, 11]

產生2到(number - 1)的數字

number為list中的每個元素,產生2到(number - 1)的數字,until是不包含number。
因為質數只能被1與本身整除,所以要從2到(本身 - 1)的數字中尋找可被整除的數字。

1
(2 until number)

list存放餘數

map,會傳回跟原本集合一樣大小的集合。
it為2到(number - 1)的數字,number是nums list的元素,別搞錯。
例:number 為 7
7 % 2 = 1
7 % 3 = 1
7 % 4 = 3
7 % 5 = 2
7 % 6 = 1
map傳回新的list,把以上的餘數都放入list中。

1
(2 until number).map { number % it}

none

擴展函式

1
2
3
4
5
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
}

重點在以下這個程式碼,若predicate Lambda傳回值為true,就返回false。

1
if (predicate(element)) return false

若list中有餘數是0,代表可以被整除,Lambda傳回值為true,none()就返回false。

1
.none{ it == 0}

filter過濾false的元素

predicate Lambda會傳回true或false,若為true就加到傳回值List中。
若為false,就不加入傳回值List中。

results matching ""

    No results matching ""