Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

دوال Higher-Order مخصصة

جزء من قسم المنطق والتدفق في رحلة Swift على Coddy — الدرس 42 من 56.

الآن يمكنك كتابة الدوال الخاصة بك من الرتبة الأعلى (higher-order functions) وستتناسب تماماً مع map و filter. الشكل دائماً هو نفسه: تأخذ معامل closure، وتستدعيه داخل الحلقة، ثم تعيد النتيجة.

extension Array {
    func myMap<T>(_ transform: (Element) -> T) -> [T] {
        var result: [T] = []
        for item in self {
            result.append(transform(item))
        }
        return result
    }
}

[1, 2, 3].myMap { $0 * 10 }       // [10, 20, 30]

إذا كانت الامتدادات تبدو أكثر من اللازم، فاكتب دالة مستقلة بدلاً من ذلك، فالفكرة هي نفسها:

func count<T>(_ items: [T], where predicate: (T) -> Bool) -> Int {
    var n = 0
    for item in items where predicate(item) {
        n += 1
    }
    return n
}

بمجرد أن تتمكن من تمرير الـ closures، تتوقف المكتبة القياسية عن الظهور كالسحر وتبدأ في الظهور كمجموعة من الأنماط التي يمكنك كتابتها بنفسك.

challenge icon

التحدي

متوسط

اكتب دالة حرة partition(_ items: [Int], by predicate: (Int) -> Bool) -> ([Int], [Int]) تقوم بالمرور على المصفوفة مرة واحدة وتعيد صفاً (tuple) (matched, rest): العناصر التي استوفت الشرط (predicate)، والبقية، كلاهما بنفس الترتيب الأصلي.

اقرأ سطرين: عدد صحيح min، ثم قائمة من الأعداد الصحيحة مفصولة بفاصلة. استخدم دالة partition الخاصة بك مع شرط (predicate) يتحقق مما إذا كان n > min. اطبع:

  1. matched: <...>
  2. rest: <...>

كل قائمة يتم دمج عناصرها باستخدام , (أو تترك فارغة عندما لا يوجد شيء لطباعته).

للمدخلات 5 / 2,7,3,8,5، المخرجات هي:

matched: 7,8
rest: 2,3,5

ورقة مرجعية

تتبع الدوال ذات الرتبة الأعلى نمطاً ثابتاً: استقبال closure، واستدعاؤه داخل حلقة تكرارية، ثم إرجاع النتيجة.

كملحق (extension):

extension Array {
    func myMap<T>(_ transform: (Element) -> T) -> [T] {
        var result: [T] = []
        for item in self {
            result.append(transform(item))
        }
        return result
    }
}
[1, 2, 3].myMap { $0 * 10 }  // [10, 20, 30]

كدالة حرة (free function):

func count<T>(_ items: [T], where predicate: (T) -> Bool) -> Int {
    var n = 0
    for item in items where predicate(item) {
        n += 1
    }
    return n
}

دالة partition تُرجع صفاً (tuple) من العناصر المتطابقة وغير المتطابقة:

func partition(_ items: [Int], by predicate: (Int) -> Bool) -> ([Int], [Int]) {
    var matched: [Int] = []
    var rest: [Int] = []
    for item in items {
        if predicate(item) { matched.append(item) }
        else { rest.append(item) }
    }
    return (matched, rest)
}

جرّب بنفسك

let min = Int(readLine()!)!
let nums = readLine()!.components(separatedBy: ",").map { Int($0)! }

// مهام مطلوبة: partition(_:by:) -> ([Int], [Int])؛ طباعة العناصر المتطابقة والباقي
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس المنطق والتدفق