تغييرات - مشروع صغير رائع جدًا
- جويل ليفين
هذه محاولة لتنفيذ الحل الموضح في مقالة ديف ديلونج ، تحرير المسافة وتحرير الخطوات.
يصف Changeset الحد الأدنى من التعديلات المطلوبة للانتقال من Collection واحدة من العناصر Equatable إلى أخرى.
لقد تم كتابته في المقام الأول لاستخدامه بالاقتران مع مصادر بيانات UITableView و UICollectionView من خلال اكتشاف الإضافات والحذف والبدائل والتحركات بين مجموعتي البيانات. ولكن يمكن استخدامه أيضًا لحساب تغييرات أكثر عمومية بين مجموعتين بيانات.
يحسب الرمز التالي الحد الأدنى من التعديلات للمثال الكنسي ، والانتقال من مجموعات String "هريرة" إلى "الجلوس":
let changeset = Changeset ( source : " kitten " , target : " sitting " )
print ( changeset )
// 'kitten' -> 'sitting':
// replace with s at offset 0
// replace with i at offset 4
// insert g at offset 6ثم ينجح التأكيد التالي:
let edits = [
Changeset < String > . Edit ( operation : . substitution , value : " s " , destination : 0 ) ,
Changeset < String > . Edit ( operation : . substitution , value : " i " , destination : 4 ) ,
Changeset < String > . Edit ( operation : . insertion , value : " g " , destination : 6 ) ,
]
assert ( changeset . edits == edits ) إذا كنت لا تريد أن تكون النفقات العامة Changeset نفسها ، والتي تخزن أيضًا مجموعات المصدر والهدف ، يمكنك استدعاء edits مباشرة (هنا مع بيانات مثال من دليل برمجة جدول Apple لنظام التشغيل iOS):
let source = [ " Arizona " , " California " , " Delaware " , " New Jersey " , " Washington " ]
let target = [ " Alaska " , " Arizona " , " California " , " Georgia " , " New Jersey " , " Virginia " ]
let edits = Changeset . edits ( from : source , to : target )
print ( edits )
// [insert Alaska at offset 0, replace with Georgia at offset 2, replace with Virginia at offset 4]لاحظ أن التغييرات تستخدم الإزاحة ، وليس المؤشرات ، للإشارة إلى عناصر في المجموعات. هذا يرجع أساسًا إلى أن المجموعات السريعة ليست مضمونة لاستخدام مؤشرات عدد صحيح من الصفر. انظر المناقشة في العدد رقم 37 لمزيد من التفاصيل.
يمكن استخدام قيم الإزاحة مباشرة في كتل الرسوم المتحركة لـ beginUpdates / endUpdates على UITableView و performBatchUpdates على UICollectionView في أن Changeset تتبع المبادئ الموضحة تحت إدراج الدُفعات ، والحذف ، وإعادة تحميل الصفوف والأقسام في دليل Apple.
باختصار؛ أولاً ، يتم إجراء جميع عمليات الحذف والبدائل ، مقارنةً بمجموعة المصدر ، ثم ، بالنسبة إلى المجموعة الناتجة ، الإدراج. الخطوة هي مجرد حذف متبوعًا بإدخال.
في إطار عمل iOS ، تم تضمين امتدادات ملائمة (واحدة على UITableView والآخر على UICollectionView ) لجعل تحديثات الجدول/المجموعة المتحركة نسيمًا. فقط اتصل update ، مثل هذا:
tableView . update ( with : changeset . edits ) بشكل افتراضي ، تستخدم Changeset == لمقارنة العناصر ، ولكن يمكنك كتابة المقارنة الخاصة بك ، الموضحة أدناه ، حيث يؤدي حدوث "A" دائمًا إلى تغيير:
let alwaysChangeA : ( Character , Character ) -> Bool = {
if $0 == " a " || $1 == " a " {
return false
} else {
return $0 == $1
}
}
let changeset = Changeset ( source : " ab " , target : " ab " , comparator : alwaysChangeA )نتيجة لذلك ، ستتألف التغييرات من استبدال "A" (إلى آخر "A"):
let expectedEdits : [ Changeset < String > . Edit ] = [ Changeset . Edit ( operation : . substitution , value : " a " , destination : 0 ) ]
assert ( changeset . edits == expectedEdits ) أحد الاستخدامات المحتملة لهذا هو عندما لا ينبغي أن تحرك الخلية في UITableView أو UICollectionView عند تغييرها.
يحتوي مشروع XCode أيضًا على هدف لتوضيح الاستخدام في التطبيق:

هذا يستخدم الامتدادات المذكورة أعلاه لتحريك التحولات بناءً على تعديلات Changeset .
هذا المشروع متاح بموجب ترخيص معهد ماساتشوستس للتكنولوجيا.
حقوق الطبع والنشر © 2015-18 ، Joachim Bondo. انظر ملف الترخيص.