الفصل الخامس :بنى المعلومات
المصفوفات
تخيل أنك مثلا تكتب برنامجا عن فصلك الذي فى المدرسة، وفيه أسماء كل الطلاب الذين في الفصل .. وعلى افتراض أنهم 30 شخص، هل تتخيل تعريف 30 متغير؟؟
إذا قلت نعم، فإنك ستتعب نفسك

الحل يكمن فى المصفوفة، وهى عبارة عن بنية للمعلومات تستخدم فى تخزين مجموعة متغيرات مرتبطة ببعض بدون إنشاء متغيرات لتشمل قيم كل واحد! .. تابع
أولا: لإنشاء كائن للمصفوفة، يوجد أكثر من طريقة ..
1- إستخدام الطريقة new من ال Array Class وهى تعطينا كائن من ال Array Class
ary=Array.new #Create an empty array.
p ary
#output: []
2- إسناد مباشر
نرجع ثانية، للطريقة new وهى لها بعض الوظائف الخاصة مثلا ال populating وهى وضع قيم بمجرد إنشاء الكائن:
ary=Array.new(4) #4 nils!
p ary
#output: [nil, nil, nil, nil]
هنا قلنا للطريقة new إننا نريد كائن من صف المصفوفة، ويكون فيه 4 عناصر .. ولكننا لم نحدد قيم العناصر ، فأخدت nil افتراضيا..
ary=Array.new(4){"test"} #array contains 4 elements all are test
p ary
#output: ["test", "test", "test", "test"]
هنا قلنا للطريقة new إننا نريد كائن من صف المصفوفة، ويكون فيه 4 عناصر وقيمة كل واحد هى "test”
فالحل الأفضل هو إنك تضع أسماء الطلاب فى Array كالتالى
students=[“ahmed”, “ayman”, “christina”, “rogina”, “wael”, “mostafa”, .... ]
لاحظ إن المصفوفة أول عنصر فيها ترتيبه 0
students=["ahmed", "christina", "rogina", "Wael", "3amer"]
p students #print the array
#output: ["ahmed", "christina", "rogina", "Wael", "3amer"]
puts students[0] طباعة العنصر الأول
#output: ahmed
puts students[0..3] العناصر ال4 الأولى
#output:
ahmed
christina
rogina
Wael
puts students[-1] #العنصر الأخير
#output: 3amer
puts "ahmed included!" if students.include?("ahmed")
#output: ahmed included!
Include?(obj)
هى طريقة "دالة" ضمن ال array class وترجع return ب true او false ، ومن الآخر معناها هل ال array بتشمل الobject أم لا.
puts students.length
#output: 5
length طريقة تعيد لنا عدد العناصر الموجودة في المصفوفة
size هى اسم مستعار لـ length
puts students.size #alias for length
#output: 5
delete_at(index)
هى طريقة تأخد 1 parameter وهو ال index للعنصر اللى تريد أن تحذفه
students.delete_at(3) #wael is removed.
p students
#output:["ahmed", "christina", "rogina", "3amer"]
هنا حذفنا العنصر الذي كان ترتيبه 3 -لاحظ إننا نبدأ الترتيب من 0 -
clear هى طريقة تستخدم لحذف كل العناصر الموجودة في المصفوفة
students.clear #delete all
p students
#output: 0
empty?
هى طريقة تعيد قيمة بولونية ب true او false فى حال إذا كانت المصفوفة لا تحوي على عناصر
students.clear
puts "Array is empty" if students.empty?
#output: Array is empty
insert(index, object)
طريقة تستخدم فى إضافة عنصر لل array عن طريق الفهرس index الذي تحدده كالتالى مثلا
students=["ahmed", "christina", "rogina", "Wael", "3amer"]
students.insert(4, "ayman")
p students
#output: ["ahmed", "christina", "rogina", "Wael", "ayman", "3amer"]
concat(array)
هى طريقة تستخدم فى إضافة array اخرى للحالية كالتالى مثلا
students=["ahmed", "christina", "rogina", "wael", "3amer"]
students.concat(["ramy", "mona", "3obaida"])
p students
#["ahmed", "christina", "rogina", "wael", "3amer", "ramy", "mona", "3obaida"]
last
هى طريقة تعيد اخر عنصر فى المصفوفة
students=["ahmed", "christina", "rogina", "Wael", "3amer"]
puts students.last #students[-1]
#output: 3amer
لاحظ إنك إذا مررت رقم إلى طريقة last فإنها تعيد إليك آخر العناصر بنفس العدد المّرر وهكذا
puts students.last(2)
#output
Wael
3amer
first
هى عكس last تماما وهى تعيد اول عنصر وإذا مررت لها رقم سيعيد لك من اول (الرقم) من المصفوفة
puts students.first
#output: ahmed
اول ثلاثة
#output
ahmed
christina
rogina
replace
هى طريقة تستخدم فى إستبدال كل العناصر بالمصفوفة بمصفوفة ثانية
langs=["Pascal", "C", "Perl"]
langs.replace(["Ruby", "Python", "C#", "Java"])
p langs
#output: ["Ruby", "Python", "C#", "Java"]
reverse
هى طريقة ترجع نسخة من المصفوفة ولكن بترتيب عكسي، انظر المثال:
reversedLangs=langs.reverse
p langs
#output:["Ruby", "Python", "C#", "Java"] .. Not Changed!
p reversedLangs
#output: ["Java", "C#", "Python", "Ruby"]
اكيد أنك لاحظت أن reverse لم تأثر على المصفوفة الأصلية .. ولكن على فرض أننا نريد أن يحدث التغيير على المصفوفة الأصلية ؟ فالحل هو إننا نستخدم reverse!
ماهى reverse! ؟
اى طريقة تجد فيها علامة التعجب "!” اعرف إنها destructive function يعنى تأثيرها سيكون على الكائن نفسه وليس على نسخته وهنا فى مثالنا، عكست العناصر فى الكائن نفسه وليس على نسخة منه:
langs=["Pascal", "C", "Perl"]
langs.reverse!
p langs
#output: ["Perl", "C", "Pascal"]
لاحظ المثال التالي للدمج:
old=["C", "Pascal", "Fortran"]
new=["Python", "Ruby", "Java"]
all= old+new #or all=old.concat(new)
p all
#output: ["C", "Pascal", "Fortran", "Python", "Ruby", "Java"]
all << "C#" # add c#
p all
#output:["C", "Pascal", "Fortran", "Python", "Ruby", "Java", "C#"]
all.push("Perl") # << perl
p all
#output: ["C", "Pascal", "Fortran", "Python", "Ruby", "Java", "C#", "Perl"]
all.pop #remove the last element.
p all
#output: ["C", "Pascal", "Fortran", "Python", "Ruby", "Java", "C#"]
تقدر تستخدمها كمجموعة وتطبق عليها حاجات مثل التقاطع والإتحاد والفرق
langs=["C", "Python", "Ruby", "Pascal"]
intrep_langs=["Python", "Ruby", "Groovy"]
في الإتحاد سنستخدم عامل or وهو ال |
#union
un=langs|intrep_langs
p un
#output: ["C", "Python", "Ruby", "Pascal", "Groovy"]
وفي الفرق سنستخدم ال minus -
#difference
diff=langs-intrep_langs
p diff
#output: ["C", "Pascal"]
وفي التقاطع سنستخدم and operator وهو &
#intersection
intSec=langs & intrep_langs
p intSec
#output: ["Python", "Ruby"]
uniq
هى طريقة تعيد لنا نسخة من المصفوفة مكونة من العناصر ولكن بدون تكرار
uniq!
هى طريقة تحذف كل التكرارات للعناصر وتجعل ظهوره مرة واحدة فقط
تابع المثال التالى لتوضيح الفكرة
ary=[1, 2, 3 ,3, 5, 6, 7, 7, 7, 10]
p ary
uniqAry=ary.uniq
p ary
p uniqAry
ary.uniq!
p ary
#output:
[1, 2, 3, 3, 5, 6, 7, 7, 7, 10]
[1, 2, 3, 3, 5, 6, 7, 7, 7, 10]
[1, 2, 3, 5, 6, 7, 10]
[1, 2, 3, 5, 6, 7, 10]
sorting
للترتيب استخدم طريقة sort وهى طريقة تعيد نسخة من المصفوفة ولكن مرتبة
اذا أردت أن يكون التعديل دائما على المصفوفة إستخدم sort!
ary=[1, 2, 5,623, 14, 512]
p ary.sort #not changed. just a copy!
#output: [1, 2, 5, 14, 512, 623]
ary.sort! #destructive
p ary
#output: [1, 2, 5, 14, 512, 623]
المدى Ranges
المدى هو عبارة عن فترة بتتكون من start, end, step
rng1to10=1..10 #10 is included
p rng1to10.to_a #to_a means to array
#output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
rng1to9= 1...10 #10 isn't included
p rng1to9.to_a
#output: [1, 2, 3, 4, 5, 6, 7, 8, 9]
min
هى طريقة تعيد لنا أصغر عناصر المدى
max
هى طريقة تعيد لنا أكبر عناصر المدى
rng=1..10
p rng.to_a
puts rng.min #min
#output 1
puts rng.max #max
#output 10
إستخدام المدى بصراحة غالبا يستخدم فى تكوين المصفوفات التي تحوي على عناصر كثيرة، مثلا
1 ل 100
او ال a to z
alphabet=('a'..'z').to_a
p alphabet
#output ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
words=('abc'..'abk').to_a
p words
["abc", "abd", "abe", "abf", "abg", "abh", "abi", "abj", "abk"]
لاحظ أن المدى انبنى بناءا على آخر حرف فعادت لنا المقطع ab + الحروف من a إلى k
include?(obj)
هى طريقة تختبر وجود كائن فى المدى او لا وتعيد ب true او false
Hashes
ال Hash عبارة عن بنى معلومات Data Structure مشهورة جدا فى العديد من اللغات ويمكن أن تكون واجهتها قبل تحت مسمى آخر مثل القاموس Dictionary فى Python او Associative array فى Perl وهكذا
ماهو ال Hash ؟
هو قاموس بالمعنى الحرفى أنت بتحدد ليه المفتاح و القيمةkey, value
اولا لإنشاء HashTable سنستخدم طريقةnew من ال Hash Class
hashTable=Hash.new #Create a new Hash object.
او
إضافة keys, values
مثال:
hashTable["name"]="ahmed"
hashTable["age"] =18
hashTable["sex"] = 'm'
p hashTable
#output: {"name"=>"ahmed", "sex"=>"m", "age"=>18}
store(key, value)
او عن طريق إستخدام طريقة store وهى تأخد بارامتراين
hash.store("lang", "ruby") #Adding key, value by using store method.
#output:{"name"=>"ahmed", "lang"=>"ruby", "sex"=>"m", "age"=>18}
استخدام القيم بال hash
نستطيع الحصول على قيمة key مخزن بال hash بإستخدام ال index او الطريقة fetch
hashTable[key] #returns the value
hashTable.fetch(key) #returns the value
hash={"name"=>"ahmed", "sex"=>"m", "age"=>18}
puts "Name: " << hash["name"]
#output: Name: ahmed
puts "sex : " << hash.fetch("sex")
#output: sex : m
clear
هي طريقة تستخدم فى حذف كل الkeys/values من ال HashObj
shift
تعيد اول Key/Value على صورة مصفوفة مكونة من عنصرين
hash={"name"=>"ahmed", "sex"=>"m", "age"=>18}
ary=hash.shift
p ary
#output: ["name", "ahmed"]
invert
هى طريقة تستخدم فى عكس ال hash فتقوم بتحول ال keys إلى values وال values إلى keys
hash={"name"=>"ahmed", "sex"=>"m", "age"=>18}
invHash=hash.invert
p invHash
#output: {"m"=>"sex", 18=>"age", "ahmed"=>"name"}
puts invHash["ahmed"]
#output: name
has_key?(key) #true/false
has_value?(value) #true/false
ال has_key هي طريقة تستخدم فى إختبار وجود key بال hash
ال has_value هي طريقة تستخدم فى إختبار وجود value بال hash
hash.has_key?("name") #true/false
hash.has_value?(18) #true/false
length
ال length هي طريقة تستخدم فى الحصول على عدد الأزواج فى ال hash
hash={"name"=>"ahmed", "sex"=>"m", "age"=>18}
puts hash.length #number of pairs
#output: 3
to_a
تستخدم فى تحويل ال hash إلى array
hash={"name"=>"ahmed", "sex"=>"m", "age"=>18}
ary=hash.to_a #convert to array
p ary
#output: [["name", "ahmed"], ["sex", "m"], ["age", 18]]
keys
هى طريقة تعيد مصفوفة تشمل كل المفاتيح الموجودة في hash
values
هى طريقة تعيد مصفوفة تشمل كل القيم الموجودة في hash
hash={"name"=>"ahmed", "sex"=>"m", "age"=>18}
keys=hash.keys
p keys
#output: ["name", "sex", "age"]
vals=hash.values
p vals
#output: ["ahmed", "m", 18]
تحويل Array ل Hash
ary=["first", 1, "second", 2, "third", 3]
hash=Hash[*ary]
p hash
#output: {"second"=>2, "first"=>1, "third"=>3}