kotlin-stdlib และถิ่นที่อยู่
ร่วมสำรวจ extension functions ในโลกมหัศจรรย์ของ Kotlin
สัปดาห์ที่แล้วผมพยายามนับ element ใน list ด้วยโค้ดประมาณนี้ครับ
data class Muggle(
var name: String,
var age: Int
)fun stupidCount(list: List<Muggle>): Int {
var n = 0
list.forEach {
if (it.age == 25)
n++
}
return n
}
แล้วเพิ่งมาตระหนักได้ว่าสามารถทำได้ด้วยโค้ดแค่นี้
val count = list.count { it.age == 25 }
วันก่อนผมพยายามแปลง List เป็น String เพื่อ log ด้วยโค้ดประมาณนี้
fun stupidLogString(list: List<Muggle>): String {
var s = ""
list.forEach {
s += "${it.name}, "
}
return s
}
แล้วเพิ่งมาตระหนักได้ว่าสามารถทำได้ด้วยโค้ดแค่นี้
val log = list.joinToString { it.name }
Standard library ของ Kotlin มีสิ่งอำนวยความสะดวกในรูปแบบของ extension functions/properties เยอะมากกกก มากจนไม่มั่นใจว่ามีอะไรบ้าง หลายครั้งเขียนโค้ดไปแล้วเพิ่งทราบว่าใน stdlib ก็มีให้ใช้ รู้สึกโง่อย่างบอกไม่ถูก ผมจึงตัดสินใจศึกษาอย่างจริงจังและบันทึกไว้บนนี้ด้วยเลย
จุดประสงค์ของบทความนี้คือสร้าง awareness เกี่ยวกับ extension functions ใน stdlibพร้อมยกตัวอย่างสั้นๆเอาไว้ ผู้อ่านควรมีความรู้ภาษา kotlin และเข้าใจ lambda expression พอสมควร
Functional Programming ง่ายๆ สไตล์ Kotlin
Higher order function and Lambda explained!
blacklenspub.com
ตัวอย่าง extension functions
data class Person(
var firstName: String,
var lastName: String,
var gender: String,
var age: Int
)
สร้าง List ด้วย listOf(), mutableListOf()
val people: List<Person> = listOf(
Person("Newt", "Scamander", "Male", 17),
Person("Queenie", "Goldstein", "Female", 18),
Person("Tina", "Goldstein", "Female", 20),
Person("Credence", "", "Male", 19),
Person("Percival", "Graves", "Male", 44)
)
สร้าง Map ด้วย mapOf(), mutableMapOf() และ Pair<K,V>
val ageMap: Map<String, Int> = mapOf(
"Newt" to 17,
"Queenie" to 18
)
แปลง List<T> เป็น List<U> ด้วย map
val nameList: List<String> = people.map { it.firstName }
// nameList = ["Newt", "Queenie", "Tina", "Credence", "Percival"]
เลือกเฉพาะไอเทมที่ต้องการด้วย filter
val teenagers: List<Person> = people.filter { it.age in 13..19 }
// Newt, Queenie, Credence
หาผลรวมด้วย sumBy
val ageSum: Int = people.sumBy { it.age }
// ageSum = 118
เรียงไอเทมด้วย sortBy
val peopleByAge = people.toMutableList().sortedBy { it.age }
// Newt, Queenie, Credence, Tina, Percival
จัดกลุ่มด้วย groupBy
val peopleByGender: Map<String, List<Person>> =
people.groupBy { it.gender }
/*
{
"Male": [Newt, Credence, Percival],
"Female": [Queenie, Tina]
}
*/
แปลง List<V> เป็น Map<K, V> ด้วย associate
val peopleByName: Map<String, Person> =
people.associateBy { it.firstName }
/*
{
"Newt": Newt,
"Queenie": Queenie,
...
}
*/
ตัวอย่าง extension properties
ใช้ lastIndex แทน size-1
val lastIndex = people.size - 1
// lastIndex = 4
val coolLastIndex = people.lastIndex
// coolLastIndex = 4
หา IntRange ด้วย indices
val indexRange = people.indicies
// indexRange = [0..4]
ทั้งหมดนี้เป็นเพียงน้ำจิ้มครับ จะยกตัวอย่างมามากกว่านี้ก็จะกลายเป็นการแปล kotlin doc ไปแทน ผมว่าเข้าไปดูเต็มๆใน stdlib.kotlin.collection stdlib.kotlin.string กันดีกว่า
สุดท้ายนี้ถ้าท่านผู้อ่านได้ประโยชน์จากบทความนี้ หรือชีวิตดีขึ้นหลังจากไปดู extension functions/properties เต็มๆมาแล้ว ผมอยากให้ช่วยกันแชร์/แนะนำต่อๆกันไปให้ developers ท่านอื่นชีวิตดีขึ้นกันถ้วนหน้าครับ