0Pricing
Kotlin Academy · درس

معاملات Flow: ‏map وfilter وtransform وtake

طبّق المعاملات الوسيطة لتحويل انبعاثات Flow والحد منها.

معاملات Flow: ‏map وfilter وtransform وtake درس مجاني في Kotlin Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Kotlin Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Kotlin Academy 4 دروس في المجموع.

ما هو Flow؟

إن Flow تدفق بارد غير متزامن. وتكون العوامل الوسيطة مثل map وfilter وtransform كسولة — فلا تعمل إلا عند جمع التدفق.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun numbers(): Flow<Int> = flow {
    repeat(5) { emit(it + 1) }
}
fun main() = runBlocking {
    numbers().collect { println(it) }
}

عامل map

يحوّل map كل قيمة مُصدرة. وهو تحويل واحد إلى واحد يُطبَّق بطريقة كسولة.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    (1..5).asFlow()
        .map { it * it }
        .collect { println(it) } // 1 4 9 16 25
}

عامل filter

يمرر filter العناصر التي تطابق المسند فقط، ويتجاهل بقية العناصر.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    (1..10).asFlow()
        .filter { it % 2 == 0 }
        .collect { println(it) } // 2 4 6 8 10
}

عامل transform

يُعد transform العامل الأكثر عمومية: إذ يمكنك إصدار صفر أو قيمة واحدة أو عدة قيم لكل عنصر إدخال.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    (1..3).asFlow()
        .transform { n ->
            emit("Item $n")
            emit("Done $n")
        }
        .collect { println(it) }
}

عامل take

يأخذ take(n) أول n عناصر فقط، ثم يلغي التدفق المصدر بعد ذلك.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    flow {
        repeat(100) { emit(it) }
    }.take(3)
     .collect { println(it) } // 0 1 2
}

takeWhile وdropWhile

يأخذ takeWhile العناصر ما دام المسند صحيحًا، بينما يتجاهل dropWhile العناصر حتى يصبح المسند خاطئًا.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    (1..10).asFlow()
        .takeWhile { it < 5 }
        .collect { println(it) } // 1 2 3 4

    (1..10).asFlow()
        .dropWhile { it < 5 }
        .collect { println(it) } // 5 6 7 8 9 10
}

تسلسل العوامل

يمكن تركيب العوامل: إذ يعيد كل عامل Flow جديدًا، مما يتيح إنشاء مسارات تعريفية.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    (1..20).asFlow()
        .filter { it % 3 == 0 }
        .map { it * 2 }
        .take(4)
        .collect { println(it) } // 6 12 18 24
}

mapNotNull

يحوّل mapNotNull القيم ويتجاهل النتائج الفارغة في خطوة واحدة — وهو مكافئ لـ map + filter { it != null }.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    flowOf("1", "two", "3", "four", "5")
        .mapNotNull { it.toIntOrNull() }
        .collect { println(it) } // 1 3 5
}

flatMapConcat

يحوّل flatMapConcat كل عنصر إلى تدفق، ثم يضم النتائج بالتتابع.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    (1..3).asFlow()
        .flatMapConcat { n -> flowOf("$n-a", "$n-b") }
        .collect { println(it) }
}

استخدام onEach للتأثيرات الجانبية

ينفذ onEach تأثيرًا جانبيًا على كل عنصر دون تغيير التدفق — وهو مناسب للتسجيل أو التحليلات داخل المسار.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    (1..5).asFlow()
        .onEach { println("Processing: $it") }
        .filter { it % 2 == 0 }
        .collect { println("Collected: $it") }
}

Flow بارد

يعيد كل استدعاء لـ collect تشغيل التدفق من البداية. ولا تُصدر أي قيمة أو تُحوّل حتى يؤدي عامل نهائي إلى بدء الجمع.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val flow = (1..3).asFlow().map { println("map $it"); it * 2 }
    println("Before collect")
    flow.collect { println("got $it") }
    println("Second collect:")
    flow.collect { println("got $it") }  // runs again
}

تحقق سريع

أي عامل يُصدر صفرًا أو قيمة واحدة أو عدة قيم لكل عنصر مصدر؟

مراجعة

يحوّل map القيم تحويلًا واحدًا إلى واحد؛ ويتجاهل filter العناصر؛ ويُصدر transform أي عدد من القيم؛ ويحد take العدد. سَلْسِلها بطريقة تعريفية — فالتدفق بارد ولا يعمل إلا عند جمعه.

الأسئلة الشائعة

هل درس «معاملات Flow: ‏map وfilter وtransform وtake» مجاني؟

نعم — نص درس «معاملات Flow: ‏map وfilter وtransform وtake» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Kotlin Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Kotlin Academy 4 دروس في المجموع.

ماذا ستتعلم في «معاملات Flow: ‏map وfilter وtransform وtake»؟

طبّق المعاملات الوسيطة لتحويل انبعاثات Flow والحد منها. تتمرن على Kotlin Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Kotlin Academy؟

لا تُشترط خبرة سابقة. Kotlin Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «معاملات Flow: ‏map وfilter وtransform وtake»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Kotlin Academy هذا؟

نعم. كل درس في Kotlin Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. معاملات Flow: ‏map وfilter وtransform وtake
  2. ‏catch وonCompletion: معالجة الأخطاء في Flow
  3. ‏combine وzip: دمج تدفقات Flow متعددة
  4. ‏flowOn وbuffer: السياق والضغط العكسي
← العودة إلى Kotlin Academy