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.

🕑 16 daqiqa o‘qish 📄 593 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. map va filter
  2. it o'rniga nom
  3. forEach va indeks
  4. Yig'ma amallar
  5. any, all, none
  6. Topish
  7. Saralash
  8. Eng kattasini topish
  9. Guruhlash
  10. associate - lug'at yasash
  11. fold va reduce
  12. take va drop
  13. zip va flatten
  14. Zanjir
  15. Xulosa

Kotlin ning standart kutubxonasi juda boy. Sikl yozib bajariladigan ishlarning aksariyati bitta funksiya bilan hal bo'ladi.

map va filter #

KOTLIN
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 })
}
Natija
[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 #

KOTLIN
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") })
}
Natija
[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 #

KOTLIN
fun main() {
    val shaharlar = listOf("Namangan", "Andijon", "Farg'ona")

    shaharlar.forEach { println("- $it") }

    shaharlar.forEachIndexed { i, shahar ->
        println("$i: $shahar")
    }
}
Natija
- Namangan
- Andijon
- Farg'ona
0: Namangan
1: Andijon
2: Farg'ona

Yig'ma amallar #

KOTLIN
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 })
}
Natija
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 #

KOTLIN
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 })
}
Natija
true
true
true
false
true
Bo'sh ro'yxatda all har doim 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 #

KOTLIN
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 })
}
Natija
4
17
null
null
15
1
MetodTopilmasa
first { }Xato beradi
find { }null
firstOrNull { }null

find va firstOrNull - bir xil narsa; find qisqaroq.

Saralash #

KOTLIN
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())
}
Natija
[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 #

KOTLIN
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 })
}
Natija
Talaba(ism=Aziza, ball=95)
Talaba(ism=Malika, ball=88)
95
[Aziza, Husanboy, Malika]
  • maxByOrNull - elementning o'zini qaytaradi.
  • maxOf - faqat qiymatni.

Guruhlash #

KOTLIN
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 })
}
Natija
[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 #

KOTLIN
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 })
}
Natija
{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}
MetodKalitQiymat
associateSiz aytasizSiz aytasiz
associateBySiz aytasizElementning o'zi
associateWithElementning o'ziSiz aytasiz

fold va reduce #

KOTLIN
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 })
}
Natija
15
15
115
12345
120

Farqi bitta: fold boshlang'ich qiymat oladi, reduce esa birinchi elementdan boshlaydi.

Bo'sh ro'yxatda reduce xato beradi

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 #

KOTLIN
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))
}
Natija
[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 #

KOTLIN
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 } })
}
Natija
[(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:

KOTLIN
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 }}")
}
Natija
Olma: 480000
Anor: 270000
Uzum: 176000
Jami: 926000
Tugagan: [Shaftoli]

Beshta amal, beshta qator. Sikl bilan bu yigirma qator bo'lardi.

Ketma-ketlik (Sequence) - katta ro'yxatlar uchun

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:

KOTLIN
ombor.asSequence()
     .filter { ... }
     .map { ... }
     .toList()

Shunda har bir element zanjir bo'ylab yakka o'zi o'tadi va oraliq ro'yxat yaratilmaydi.

Amaliy topshiriq
  1. Sonlar ro'yxatini map bilan ikkilantiring.
  2. Juft sonlarni filter bilan ajrating.
  3. it o'rniga o'z nomingizni bering.
  4. sumOf bilan umumiy narxni hisoblang.
  5. Bo'sh ro'yxatda all nima qaytarishini tekshiring.
  6. first { } va find { } ni topilmaydigan shart bilan sinang.
  7. Talabalarni ball bo'yicha saralang.
  8. groupBy bilan guruhlarga ajrating va sonini chiqaring.
  9. fold bilan ko'paytmani hisoblang.
  10. Beshta amaldan iborat zanjir yozing.

Xulosa #

  • map o'zgartiradi, filter tanlaydi - 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 all har doim true.
  • first { } topmasa xato beradi, find { } esa null.
  • Saralash funksiyalari yangi ro'yxat qaytaradi.
  • groupBy guruhlaydi, associateBy lug'at yasaydi.
  • fold boshlang'ich qiymat oladi, reduce esa bo'sh ro'yxatda xato beradi.
  • Katta ro'yxatlar uchun asSequence().

Keyingi bo'limda sinflar va obyektlarga o'tamiz.

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.