توفّر Swift وظائف غنية في مكتبتها القياسية، لكن يمكنك الوصول إلى مزيد من الميزات باستيراد مكتبات وأُطر عمل خارجية. قد تأتي هذه الوحدات مباشرةً من مشروع Swift (مثل Swift Argument Parser)، أو من أُطر عمل منصّات Apple (مثل Foundation وNetwork Framework)، أو من مكتبات مفتوحة المصدر من أطراف ثالثة (مثل SwiftyBeaver).
الوحدات الأساسية مثل Foundation، وهي من أكثر المكتبات استخدامًا في Swift، تأتي مضمّنة مع مجموعة أدوات Swift. أما مكتبات الأطراف الثالثة فيجب إضافتها إلى إعدادات مشروعك (مثلًا باستخدام Swift Package Manager) قبل أن تتمكن من استيرادها.
يتم استيراد الوحدات بكتابة الكلمة المفتاحية import متبوعةً باسم الوحدة.
لذا يمكنك استيراد Foundation بإضافة ما يلي إلى برنامجك.
import Foundation
استيراد وحدة يجعل أنواعها وطرقها ودوالها متاحةً لكودك.
على سبيل المثال، يوسّع استيراد Foundation النوع String بطرق مساعدة مفيدة مثل components(separatedBy:).
بحسب العُرف، توضع عبارات import في أعلى ملف Swift حتى تكون التبعيات ظاهرةً مباشرةً لأي شخص يقرأ الكود.
يمكن الوصول إلى المحارف المفردة في String باستخدام أسلوب الفهرسة المستخدم مع المصفوفات.
لكن الفهارس المستخدمة مع السلاسل النصية ليست أعدادًا صحيحة ولا يمكن التعامل معها مباشرةً.
بدلًا من ذلك يجب حسابها انطلاقًا من فهرس آخر معروف، مثل startIndex، الذي يشير إلى موضع أول محرف في سلسلة نصية غير فارغة، وذلك باستخدام الطرق المتاحة في مكتبتي String وNSString (فعند استيراد وحدة Foundation، تتمكن السلاسل النصية في Swift من الوصول إلى جميع خصائص NSString وطرقه).
على سبيل المثال، لنأخذ السلسلة النصية التالية:
let csv = "apple,pear,peach,orange,cherry,lime,goosberry"
لا يمكنك كتابة csv[21] للحصول على الحرف "g" في "orange"، بل يجب بدلًا من ذلك حساب قيمة من النوع String.Index وتمرير ذلك الفهرس.
لاحظ أن هذه الفهارس ليست مخصصة لأن يفهمها البشر بمفردها.
فهي ما يُشار إليه باسم الفهارس المعتمة، إذ لا يحتاج البشر إلى معرفة ما بداخلها.
let index = csv.index(csv.startIndex, offsetBy: 21)
csv[index]
// "g"
print(index)
// prints Index(_rawBits: 1376513)
لكن لاحظ أنه إذا لم تكن قيمة الإزاحة فهرسًا صالحًا، أي إذا كانت ستُرجع فهرسًا قبل startIndex أو بعد endIndex، فستُطلق العملية خطأً يؤدي إلى انهيار البرنامج.
ولمنع هذه المشكلة، يمكنك تحديد فهرس مُقيّد.
تُرجع هذه العملية فهرسًا اختياريًا، وستُرجع nil للفهارس غير الصالحة في غير ذلك.
let tooFar = csv.index(csv.startIndex, offsetBy: 200)
// error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
let tooFarButSafe = csv.index(csv.startIndex, offsetBy: 200, limitedBy: csv.endIndex)
// nil
بالإضافة إلى ذلك، لا يمكن مشاركة الفهارس بين السلاسل النصية.
فمثلًا، استخدام index للحرف "g" في "orange" المحسوب أعلاه للفهرسة داخل السلسلة fam = "This is my family: 👨👩👦👦, this is our dog: 🐶, this is our cat: 🐱!"، أي fam[index]، سيؤدي إلى انهيار برنامجك.
هناك أسباب كثيرة لكل هذا، لكنها جميعًا تعود في الأساس إلى أن "يونيكود معقّد".
وبشكل عام، إذا كنت تحتاج إلى وصول عشوائي إلى المحارف المفردة، فالأرجح أنك تريد استخدام بنية بيانات أخرى، مثل Array<Character>.
توفّر Swift الطريقتين first وlast للحصول على أول محرف وآخر محرف في السلسلة النصية.
تُرجع هاتان الطريقتان محرفًا اختياريًا، لذا إذا كانت السلسلة النصية فارغة فستُرجعان nil.
let str = "Hello, world!"
print(str.first) // Prints Optional("H")
print(str.last) // Prints Optional("!")
يمكنك أيضًا استخدام الطريقتين prefix وsuffix للحصول على سلسلة نصية فرعية.
تأخذ هاتان الطريقتان عددًا صحيحًا كوسيط وتُرجعان سلسلة نصية فرعية تحتوي على أول n محرف أو آخر n محرف من السلسلة النصية.
let str = "Hello, world!"
print(str.prefix(5)) // Prints "Hello"
print(str.suffix(6)) // Prints "world!"
التعامل مع النصوص مهمة شائعة في البرمجة. وتوفّر Swift، إلى جانب إطار عمل Foundation، العديد من الطرق والخصائص الملائمة لفحص السلاسل النصية وتحويلها ومعالجتها.
components(separatedBy:)
لتقسيم سلسلة نصية إلى مصفوفة من السلاسل النصية الفرعية بناءً على فاصل، استخدم components(separatedBy:) (يتطلب استيراد Foundation):
import Foundation
let sentence = "Hello, world!"
let words = sentence.components(separatedBy: " ")
print(words) // Prints ["Hello,", "world!"]
hasPrefix(_:) وhasSuffix(_:)
للتحقق مما إذا كانت سلسلة نصية تبدأ أو تنتهي بتسلسل معيّن من المحارف، استخدم hasPrefix(_:) وhasSuffix(_:):
let greeting = "Hello, world!"
print(greeting.hasPrefix("Hello")) // Prints true
print(greeting.hasSuffix("world!")) // Prints true
يمكنك تغيير حالة الأحرف في سلسلة نصية باستخدام هذه الطرق والخصائص القياسية:
lowercased(): تُرجع نسخة من السلسلة النصية بأحرف صغيرة.uppercased(): تُرجع نسخة من السلسلة النصية بأحرف كبيرة.capitalized: تُرجع نسخة يكون فيها أول حرف من كل كلمة كبيرًا (من Foundation).let greeting = "hello, world!"
print(greeting.lowercased()) // Prints "hello, world!"
print(greeting.uppercased()) // Prints "HELLO, WORLD!"
print(greeting.capitalized) // Prints "Hello, World!"
replacingOccurrences(of:with:)
لاستبدال كل حالات ظهور سلسلة نصية فرعية مستهدفة بسلسلة أخرى، استخدم replacingOccurrences(of:with:) (من Foundation):
let greeting = "Hello, world!"
let updated = greeting.replacingOccurrences(of: "world", with: "Swift")
print(updated) // Prints "Hello, Swift!"
joined(separator:)
تنتمي الطريقة joined(separator:) إلى مجموعات السلاسل النصية، مثل [String].
وهي تضم العناصر معًا في سلسلة نصية واحدة باستخدام فاصل:
let words = ["Hello", "world"]
let sentence = words.joined(separator: ", ")
print(sentence) // Prints "Hello, world"
افتتح نادٍ جديد للشعر في المدينة، وأنت تفكر في الانضمام إليه. ولأنه كانت هناك حوادث في الماضي، فإن النادي يتبع سياسة دقيقة للغاية بشأن الأبواب، وعليك أن تتقنها قبل أن تحاول الدخول.
يوجد بابان في نادي الشعر، وكلاهما محروس. لكي تتمكن من الدخول، عليك أن تعرف كلمة السر الخاصة بذلك اليوم:
أول شيء عليك فعله هو تقسيم القصيدة إلى أسطر منفردة. سيُلقي الحارس قصيدة، وعليك أن تقسّمها إلى أسطر.
نفّذ الدالة splitOnNewlines التي تأخذ سلسلة نصية وتقسّمها إلى مصفوفة من السلاسل النصية، باستخدام محرف السطر الجديد كفاصل.
يجب أن تُرجع الدالة مصفوفة من السلاسل النصية، حيث تمثل كل سلسلة سطرًا من القصيدة.
splitOnNewlines("Hello.\nHow are you?\n\nI'm doing fine.")
// returns ["Hello." ,"How are you?", "", "I'm doing fine"].
_ بدلًا منه.على سبيل المثال، أحد كتّابهم المفضلين هو Michael Lockwood، وقد كتب القصيدة الأكروستيكية التالية، أي قصيدة يشكّل الحرف الأول من كل جملة فيها كلمة:
Stands so high
Huge hooves too
Impatiently waits for
Reins and harness
Eager to leave
عندما يُلقي الحارس القصيدة، ستقسّمها إلى أسطر منفردة وتردّ بالحروف الأولى من كل سطر، أي ["S", "H", "I", "R", "E"].
ثم يعطيك الحارس الكلمة المكوّنة من مصفوفة الأحرف التي رددت بها، لتحوّلها إلى صيغة كلمة بحروف كبيرة.
وأخيرًا، كلمة السر التي ستُرجعها هي "SHIRE"، وستتمكن من الدخول.
نفّذ الدالة frontDoorPassword التي تأخذ سلسلة نصية تمثّل القصيدة.
يجب أن تُرجع الدالة كلمة السر التي ستعطيها للحارس.
frontDoorPassword("Stands so high\nHuge hooves too\nImpatiently waits for\nReins and harness\nEager to leave")
// returns "SHIRE"
في الجزء الخلفي من النادي ستجد أشهر الشعراء، وهو أشبه بمنطقة كبار الشخصيات. ولأن هذا الباب ليس للجميع، فإن عملية الباب الخلفي أكثر تعقيدًا بعض الشيء.
", please" إلى نهاية الكلمة المكوّنة من الأحرف.على سبيل المثال، القصيدة المذكورة سابقًا هي أيضًا التيليستيكية، أي أن الحرف الأخير من كل جملة يشكّل كلمة:
Stands so high
Huge hooves too
Impatiently waits for
Reins and harness
Eager to leave
عندما يُلقي الحارس القصيدة، ستقسّمها إلى أسطر منفردة، وتزيل أي مسافات زائدة في نهايتها، وتردّ بالحروف الأولى من كل سطر، أي ["h", "o", "r", "s", "e"].
ثم يعطيك الحارس الكلمة المكوّنة من مصفوفة الأحرف التي رددت بها، لتحوّلها إلى صيغة كلمة بحروف كبيرة وتضيف إليها ", please".
وأخيرًا، كلمة السر التي ستُرجعها هي "horse, please"، وستتمكن من الدخول.
نفّذ الدالة backDoorPassword التي تأخذ سلسلة نصية تمثّل القصيدة.
يجب أن تُرجع الدالة كلمة السر التي ستعطيها للحارس.
backDoorPassword("Stands so high\nHuge hooves too\nImpatiently waits for\nReins and harness\nEager to leave")
// returns "horse, please"
داخل الغرفة الخلفية في النادي يوجد باب آخر يؤدي إلى الغرفة السرية التي لا يدخلها إلا كبار الشعراء.
"!" إلى نهاية الكلمة المكوّنة من الأحرف.على سبيل المثال، نسخة معدّلة من القصيدة المذكورة سابقًا تناسب هذا النمط:
Stands so high
Huge hooves too
Impatiently waits for
Rider with harness
Eager to leave
عندما يُلقي الحارس القصيدة، ستقسّمها إلى أسطر منفردة، وتزيل أي مسافات زائدة في نهايتها، وتردّ بالحروف رقم ith من كل سطر، أي ["S", "u", "p", "e", "r"].
ثم يعطيك الحارس الكلمة المكوّنة من مصفوفة الأحرف التي رددت بها، لتحوّلها إلى صيغة كلمة بحروف كبيرة وتضيف إليها "!".
وأخيرًا، كلمة السر التي ستُرجعها هي SUPER!، وستتمكن من الدخول.
نفّذ الدالة secretRoomPassword التي تأخذ سلسلة نصية تمثّل القصيدة.
يجب أن تُرجع الدالة كلمة السر التي ستعطيها للحارس.
secretRoomPassword("Stands so high\nHuge hooves too\nImpatiently waits for\nRider with harness\nEager to leave")
// returns "SUPER!"
سجّل في Exercism لتتعلّم وتتقن Swift عبر 35 مفهومًا116 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.