10-bo‘lim
Kolleksiya amallari
map, filter va forEach, saralash, groupBy va associate, fold va reduce, any va all, zip va chunked - Kotlin ning eng kuchli tomoni.
Ushbu bo‘lim mundarijasi
Kotlin ning standart kutubxonasi juda boy. Sikl yozib bajariladigan ishlarning aksariyati bitta funksiya bilan hal bo'ladi.
map va filter #
fun main() {
val sonlar = listOf(4, 17, 8, 23, 15, 42)
println(sonlar.map { it * 2 })
println(sonlar.filter { it > 10 })
println(sonlar.filter { it % 2 == 0 }.map { it / 2 })
println(sonlar.filterNot { it > 10 })
}
[8, 34, 16, 46, 30, 84]
[17, 23, 15, 42]
[2, 4, 21]
[4, 8]
map- har bir elementni o'zgartiradi, yangi ro'yxat qaytaradi.filter- shartga mos kelganlarini qoldiradi.
it - lambda ichidagi joriy element. Agar parametr bitta bo'lsa,
nom berish shart emas.
it o'rniga nom #
fun main() {
val ismlar = listOf("malika", "husanboy", "aziza")
println(ismlar.map { it.replaceFirstChar { c -> c.uppercase() } })
println(ismlar.map { ism -> ism.length })
println(ismlar.filter { ism -> ism.startsWith("a") })
}
[Malika, Husanboy, Aziza]
[6, 8, 5]
[aziza]
Ichma-ich lambda bo'lganda it ikki marta ishlatilsa chalkashadi -
shuning uchun ichkisiga nom berildi.
forEach va indeks #
fun main() {
val shaharlar = listOf("Namangan", "Andijon", "Farg'ona")
shaharlar.forEach { println("- $it") }
shaharlar.forEachIndexed { i, shahar ->
println("$i: $shahar")
}
}
- Namangan
- Andijon
- Farg'ona
0: Namangan
1: Andijon
2: Farg'ona
Yig'ma amallar #
fun main() {
val ballar = listOf(88, 92, 75, 95, 61)
println(ballar.size)
println(ballar.sum())
println(ballar.average())
println(ballar.max())
println(ballar.min())
println(ballar.count { it >= 85 })
println(ballar.sumOf { it * 2 })
}
5
411
82.2
95
61
3
822
sumOf - "har biridan shuni olib qo'sh" degani. map { }.sum() dan
tezroq, chunki oraliq ro'yxat yaratmaydi.
any, all, none #
fun main() {
val ballar = listOf(88, 92, 75, 95, 61)
println(ballar.any { it > 90 })
println(ballar.all { it >= 60 })
println(ballar.none { it < 50 })
val bosh = emptyList<Int>()
println(bosh.any { it > 0 })
println(bosh.all { it > 0 })
}
true
true
true
false
true
Oxirgi natijaga diqqat qiling: bo'sh ro'yxat uchun all true
qaytardi.
Bu xato emas, matematik mantiq: "hamma elementlar shartga mos keladi" - agar element bo'lmasa, bu gap avtomatik rost bo'ladi.
Amalda bu kutilmagan xatoga olib kelishi mumkin. Shuning uchun
all dan oldin isNotEmpty() ni tekshirish kerak bo'lishi mumkin.
Topish #
fun main() {
val sonlar = listOf(4, 17, 8, 23, 15)
println(sonlar.first())
println(sonlar.first { it > 10 })
println(sonlar.find { it > 100 })
println(sonlar.firstOrNull { it > 100 })
println(sonlar.last { it < 20 })
println(sonlar.indexOfFirst { it > 10 })
}
4
17
null
null
15
1
| Metod | Topilmasa |
|---|---|
first { } | Xato beradi |
find { } | null |
firstOrNull { } | null |
find va firstOrNull - bir xil narsa; find qisqaroq.
Saralash #
fun main() {
val ismlar = listOf("Nodira", "Aziza", "Husanboy", "Malika")
println(ismlar.sorted())
println(ismlar.sortedDescending())
println(ismlar.sortedBy { it.length })
println(ismlar.sortedByDescending { it.length })
println(ismlar.reversed())
val sonlar = listOf(3, 1, 4, 1, 5)
println(sonlar.sorted())
}
[Aziza, Husanboy, Malika, Nodira]
[Nodira, Malika, Husanboy, Aziza]
[Aziza, Nodira, Malika, Husanboy]
[Husanboy, Nodira, Malika, Aziza]
[Malika, Husanboy, Aziza, Nodira]
[1, 1, 3, 4, 5]
Diqqat: bularning hammasi yangi ro'yxat qaytaradi - asl ro'yxat
o'zgarmaydi. MutableList da o'zini o'zgartiradigan sort() ham bor.
Eng kattasini topish #
data class Talaba(val ism: String, val ball: Int)
fun main() {
val talabalar = listOf(
Talaba("Malika", 88),
Talaba("Husanboy", 92),
Talaba("Aziza", 95)
)
println(talabalar.maxByOrNull { it.ball })
println(talabalar.minByOrNull { it.ball })
println(talabalar.maxOf { it.ball })
println(talabalar.sortedByDescending { it.ball }.map { it.ism })
}
Talaba(ism=Aziza, ball=95)
Talaba(ism=Malika, ball=88)
95
[Aziza, Husanboy, Malika]
maxByOrNull- elementning o'zini qaytaradi.maxOf- faqat qiymatni.
Guruhlash #
data class Talaba(val ism: String, val ball: Int, val guruh: String)
fun main() {
val talabalar = listOf(
Talaba("Malika", 88, "A"),
Talaba("Husanboy", 92, "B"),
Talaba("Nodira", 75, "A"),
Talaba("Aziza", 95, "B"),
Talaba("Kamola", 61, "A")
)
val guruhlar = talabalar.groupBy { it.guruh }
println(guruhlar.keys.sorted())
for (kalit in guruhlar.keys.sorted()) {
val a = guruhlar[kalit]!!
val ortacha = a.map { it.ball }.average()
println("$kalit: ${a.size} talaba, o'rtacha $ortacha")
}
println(talabalar.groupBy { it.guruh }.mapValues { it.value.size })
}
[A, B]
A: 3 talaba, o'rtacha 74.66666666666667
B: 2 talaba, o'rtacha 93.5
{A=3, B=2}
groupBy natijasi - Map<String, List<Talaba>>. mapValues esa
har bir ro'yxatni boshqa qiymatga almashtiradi, bu yerda - uning
o'lchamiga.
Diqqat: guruhlar.keys.sorted() ishlatildi. groupBy tartibni
kafolatlamaydi, shuning uchun chiqishda aniq saralash kerak.
associate - lug'at yasash #
data class Talaba(val ism: String, val ball: Int)
fun main() {
val talabalar = listOf(
Talaba("Malika", 88),
Talaba("Husanboy", 92)
)
println(talabalar.associate { it.ism to it.ball })
println(talabalar.associateBy { it.ism })
println(talabalar.associateWith { it.ball > 90 })
}
{Malika=88, Husanboy=92}
{Malika=Talaba(ism=Malika, ball=88), Husanboy=Talaba(ism=Husanboy, ball=92)}
{Talaba(ism=Malika, ball=88)=false, Talaba(ism=Husanboy, ball=92)=true}
| Metod | Kalit | Qiymat |
|---|---|---|
associate | Siz aytasiz | Siz aytasiz |
associateBy | Siz aytasiz | Elementning o'zi |
associateWith | Elementning o'zi | Siz aytasiz |
fold va reduce #
fun main() {
val sonlar = listOf(1, 2, 3, 4, 5)
println(sonlar.reduce { a, b -> a + b })
println(sonlar.fold(0) { a, b -> a + b })
println(sonlar.fold(100) { a, b -> a + b })
println(sonlar.fold("") { a, b -> "$a$b" })
println(sonlar.reduce { a, b -> a * b })
}
15
15
115
12345
120
Farqi bitta: fold boshlang'ich qiymat oladi, reduce esa
birinchi elementdan boshlaydi.
reduce birinchi elementni boshlang'ich qiymat sifatida oladi -
shuning uchun bo'sh ro'yxatda uni ololmaydi va istisno ko'taradi.
fold da esa boshlang'ich qiymat siz tomondan berilgani uchun bunday
muammo yo'q.
Shubhalansangiz - fold ishlating.
take va drop #
fun main() {
val sonlar = listOf(1, 2, 3, 4, 5, 6, 7, 8)
println(sonlar.take(3))
println(sonlar.drop(5))
println(sonlar.takeWhile { it < 4 })
println(sonlar.dropWhile { it < 4 })
println(sonlar.takeLast(2))
println(sonlar.chunked(3))
println(sonlar.windowed(3))
}
[1, 2, 3]
[6, 7, 8]
[1, 2, 3]
[4, 5, 6, 7, 8]
[7, 8]
[[1, 2, 3], [4, 5, 6], [7, 8]]
[[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7], [6, 7, 8]]
chunked- teng bo'laklarga ajratadi.windowed- siljuvchi oyna.
zip va flatten #
fun main() {
val ismlar = listOf("Malika", "Husanboy", "Aziza")
val ballar = listOf(88, 92, 95)
println(ismlar.zip(ballar))
println(ismlar.zip(ballar) { i, b -> "$i: $b" })
val guruhlar = listOf(listOf(1, 2), listOf(3, 4), listOf(5))
println(guruhlar.flatten())
println(guruhlar.flatMap { it.map { x -> x * 10 } })
}
[(Malika, 88), (Husanboy, 92), (Aziza, 95)]
[Malika: 88, Husanboy: 92, Aziza: 95]
[1, 2, 3, 4, 5]
[10, 20, 30, 40, 50]
Zanjir #
Bu funksiyalarning kuchi - ularni birlashtirishda:
data class Mahsulot(val nom: String, val narx: Int, val soni: Int)
fun main() {
val ombor = listOf(
Mahsulot("Olma", 12000, 40),
Mahsulot("Anor", 18000, 15),
Mahsulot("Uzum", 22000, 8),
Mahsulot("Shaftoli", 9500, 0)
)
val hisobot = ombor
.filter { it.soni > 0 }
.sortedByDescending { it.narx * it.soni }
.map { "${it.nom}: ${it.narx * it.soni}" }
hisobot.forEach { println(it) }
println("Jami: ${ombor.sumOf { it.narx * it.soni }}")
println("Tugagan: ${ombor.filter { it.soni == 0 }.map { it.nom }}")
}
Olma: 480000
Anor: 270000
Uzum: 176000
Jami: 926000
Tugagan: [Shaftoli]
Beshta amal, beshta qator. Sikl bilan bu yigirma qator bo'lardi.
Zanjirdagi har bir amal oraliq ro'yxat yaratadi. Uchta amal - uchta ro'yxat.
Kichik ro'yxatlar uchun bu muammo emas. Million element bo'lsa esa
asSequence() qo'shing:
ombor.asSequence()
.filter { ... }
.map { ... }
.toList()
Shunda har bir element zanjir bo'ylab yakka o'zi o'tadi va oraliq ro'yxat yaratilmaydi.
- Sonlar ro'yxatini
mapbilan ikkilantiring. - Juft sonlarni
filterbilan ajrating. ito'rniga o'z nomingizni bering.sumOfbilan umumiy narxni hisoblang.- Bo'sh ro'yxatda
allnima qaytarishini tekshiring. first { }vafind { }ni topilmaydigan shart bilan sinang.- Talabalarni ball bo'yicha saralang.
groupBybilan guruhlarga ajrating va sonini chiqaring.foldbilan ko'paytmani hisoblang.- Beshta amaldan iborat zanjir yozing.
Xulosa #
mapo'zgartiradi,filtertanlaydi - ikkalasi ham yangi ro'yxat qaytaradi.it- lambda ning yagona parametri; ichma-ich lambda bo'lsa nom bering.sumOf,count { },average()- yig'ma amallar.- Bo'sh ro'yxatda
allhar doimtrue. first { }topmasa xato beradi,find { }esanull.- Saralash funksiyalari yangi ro'yxat qaytaradi.
groupByguruhlaydi,associateBylug'at yasaydi.foldboshlang'ich qiymat oladi,reduceesa bo'sh ro'yxatda xato beradi.- Katta ro'yxatlar uchun
asSequence().
Keyingi bo'limda sinflar va obyektlarga o'tamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.