(1) SET IN DART

في لغة Dart، الكلمة المفتاحية Set تُستخدم لتعريف مجموعة غير مرتبة من القيم الفريدة (أي لا تحتوي على عناصر مكررة).

تُعتبر Set نوعًا من أنواع البيانات الشائعة في Dart وتستخدم عندما تحتاج إلى تخزين عناصر غير مكررة دون الاهتمام بترتيبها.

✅ الخصائص الأساسية للـ Set
  1. غير مرتبة (Unordered)
    لا تضمن Set ترتيب العناصر كما أُضيفت.
  2. لا تقبل التكرار (No Duplicates)
    إذا حاولت إضافة عنصر مكرر، سيتم تجاهله.
  3. أنواع البيانات
    يمكن لـ Set أن تحتوي على أي نوع من البيانات (int, String, …).
🔹 إنشاء Set في Dart
void main() {
  Set<String> fruits = {'apple', 'banana', 'orange'};
  print(fruits); // {apple, banana, orange}
}
PHP
  • لاحظ الأقواس {}، لكن إذا أردت مجموعة فارغة، لا تستخدم {} لأنها تُمثل Map، بل استخدم Set():
Set<String> emptySet = Set(); // أو Set<String>()
PHP
🔹 إضافة عناصر
Set<int> numbers = {1, 2, 3};
numbers.add(4);
numbers.add(2); // لن يُضاف لأنه مكرر
print(numbers); // {1, 2, 3, 4}
PHP
🔹 إضافة أكثر من عنصر دفعة واحدة
numbers.addAll([5, 6, 7]);
PHP
🔹 حذف عنصر
numbers.remove(3); // يحذف العنصر 3
PHP
🔹 التحقق من وجود عنصر
print(numbers.contains(2)); // true
PHP
🔹 معرفة عدد العناصر
print(numbers.length);
print(numbers.first);
print(numbers.last);
print(numbers.isEmpty);
print(numbers.isNotEmpty);
PHP
🔹 التكرار (Looping)
for (var num in numbers) {
  print(num);
}
PHP
🔹 تحويل Set إلى List والعكس
Set<String> names = {'Ali', 'Omar', 'Sara'};
List<String> namesList = names.toList();

List<int> myList = [1, 2, 2, 3];
Set<int> mySet = myList.toSet(); // {1, 2, 3}
PHP
🔹 العمليات على Sets (التقاطع، الاتحاد، الفرق)
Set<int> a = {1, 2, 3};
Set<int> b = {3, 4, 5};

print(a.union(b));       // {1, 2, 3, 4, 5}
print(a.intersection(b)); // {3}
print(a.difference(b));   // {1, 2}
PHP
🔹 الخصائص والدوال المهمة
الخاصية / الدالةالشرح
add(value)يضيف عنصر
remove(value)يحذف عنصر
contains(value)يتحقق من وجود عنصر
lengthعدد العناصر
clear()يمسح جميع العناصر
isEmpty / isNotEmptyهل المجموعة فارغة أم لا
toList()يحول إلى قائمة
elementAt(index)يجلب عنصر حسب الفهرس (لكن لا يُنصح به لأن Set غير مرتبة)
📌 ملاحظات مهمة
  • لا تستخدم elementAt إلا للقراءة المؤقتة، لأن Set غير مرتبة وقد يتغير الترتيب في كل مرة.
  • في حال كنت بحاجة لحفظ البيانات مع الحفاظ على الترتيب، استخدم List بدلًا من Set.
✅ مثال تطبيقي شامل
void main() {
  Set<String> students = {'Ali', 'Sara', 'Mohamed'};

  students.add('Omar');
  students.add('Ali'); // لن يُضاف

  print("الطلاب: $students"); // {Ali, Sara, Mohamed, Omar}

  print("هل يوجد Sara؟ ${students.contains('Sara')}");

  students.remove('Mohamed');

  print("عدد الطلاب: ${students.length}");

  print("الطلاب واحداً تلو الآخر:");
  for (var name in students) {
    print(name);
  }
}
PHP
✅ 1. أنواع Sets: HashSet وLinkedHashSet وSplayTreeSet

في Dart، Set هي واجهة (interface)، ويوجد عدة أنواع منها:

النوعالوصف
HashSetالافتراضي في Dart. لا يضمن الترتيب. أداءه عالي عند الإضافة والبحث.
LinkedHashSetيحافظ على ترتيب الإدخال. مفيد عندما تحتاج لترتيب ثابت للعناصر.
SplayTreeSetيقوم بترتيب العناصر ترتيبًا طبيعيًا (مثل الأرقام أو الحروف). مفيد للترتيب التلقائي، لكنه أبطأ من HashSet.
مثال:
import 'dart:collection';

void main() {
  var orderedSet = LinkedHashSet<String>();
  orderedSet.addAll(['banana', 'apple', 'orange']);
  print(orderedSet); // يحافظ على ترتيب الإدخال

  var sortedSet = SplayTreeSet<int>();
  sortedSet.addAll([10, 2, 5]);
  print(sortedSet); // يتم ترتيب العناصر تلقائيًا: {2, 5, 10}
}
PHP
✅ 3. Set is Iterable (قابل للتكرار)

Set تطبّق واجهة Iterable، لذا يمكنك استخدام كل دوال Iterable مثل:

  • where
  • map
  • forEach
  • any, every
  • reduce, fold

مثال:

var numbers = {1, 2, 3, 4, 5};

var even = numbers.where((n) => n.isEven);
print(even); // (2, 4)
PHP
✅ 4. الفرق بين Set و List من حيث الأداء
العمليةListSet (HashSet)
contains()O(n)O(1) تقريبا
add()O(1)O(1)
يسمح بالتكرار؟نعملا
يحافظ على الترتيب؟نعملا (إلا مع LinkedHashSet)
✅ 5. استخدام spread operator و if داخل Set

Dart تدعم spread operator و collection if داخل المجموعات:

var addExtra = true;
var baseSet = {'a', 'b', 'c'};
var fullSet = {
  ...baseSet,
  if (addExtra) 'd',
};
print(fullSet); // {a, b, c, d}
PHP
✅ 6. الفرق بين Set و Map
Set<String> s = {'one', 'two'};       // فقط القيم
Map<String, int> m = {'one': 1};      // مفتاح وقيمة
PHP
🟢 الخلاصة:
الخاصيةSet
تخزين عناصر فريدة فقط✅ نعم
الترتيب مضمون❌ لا (إلا في LinkedHashSet)
التكرار ممكن✅ نعم
كائنات مخصصة تحتاج == و hashCode✅ نعم
أداء عالي للبحث والإضافة✅ (خاصة HashSet)

إذا كنت تفكر في استخدامات متقدمة مثل فلترة بيانات كبيرة أو البحث السريع أو تجنب التكرار، فإن Set خيار ممتاز في Dart.