Data Structures: Objects and Arrays

الأرقام، القيم المنطقية, والسلاسل النصية هي بمثابة الطوب التي تبنى به هيكلة البيانات Data structure, لكن بطبيعة الحال لا يمكنك بناء منزل كامل من آجرة أو طوبة واحدة، فالكائنات تسمح لنا بتحميع القيم بما فيها كائنات أخرى مع بعض مما يسمح لنا ببناء هياكل أكثر تعقيدا.

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

يعمل الفصل على تقديم أمثلة برمجية أكثر أو أقل واقعية، وتقديم المفاهيم التي تنطبق على المشكلة المطروحة الأمثلة البرمجية ستكون في وظائف و متغيرات والتي تم التطرق اليها من قبل.

الويريسكويرل

من حين إلى آخر و عادة من التاسعة إلى العاشرة مساء يجد جاك نفسه قد تحول إلى قارض صغير مع ذيل كثيف.

من ناحية أخرى فجاك مسرور لعدم ابتلائه بالليكانثروب الكلاسيكية، فالتحول إلى سنجاب أقل تسببا بالمشاكل من التحول إلى ذئب.فبدل شعوره بالقلق حيال أكل جيرانه (هذا سيكون غريبا) هو يقلق من أكل قط الجيران له، فبعد مناسبتين من استيقاظه على غصن رقيق و غير مستقر على شجرة البلوط عاريا و مشوش الفكر قرر غلق الأبواب و النوافذ أثناء الليل ووضع بضع الجوز على الأرض لإبقاء نفسه مشغولا

الويريسكويرل

هذا كفيل بتجنب مشاكل القط و البلوط، ولكن جاك مازال يعاني من حالته، ظهور هذا التغير الشاذ جعله يفكر في أن هذه الحادثة قد تكون ناجمة عن شيء ما لفترة كان يعتقد أن هذا التغير كان يحدث فقط في الأيام التي يلامس فيها الأشجار فقرر التوقف عن ملامستهم أو حتى الإقتراب منهم ولكن المشكلة ظلت تلاحقه.](10613180113 ثم تحول الأمر إلى نهج أكثر علمي فقرر جاك تسجيل سجل يومي لجميع مايفعله في ذلك اليوم و ماإذا كان سيتحول أو لا ، مع هذه البيانات كان يأمل جاك في تضييق الظروف التي تسبب التحول باستمرار والتي من شأنها أن تسبب هذا التحول.

تعيين البيانات

للعمل مع قطعة بيانات رقمية، علينا أولا ايجاد طريقة لتمثيلها على ذاكرة الجهاز، فلنفرض مثلا أننا نريد تمثيل مجموعة من الأعداد : 2, 3, 5, 7, و 11.

يمكننا أن نستخدم السلاسل النصية ، فبعد كل شيء السلاسل النصية يمكنها أخذ أي طول، و هذا ما يمكننا من وضع الكثير من البيانات داخلها، فنضعها على هذا الشكل "2 3 5 7 11" كما هو مبين في المثال. ولكن هذا غريب نوعا ما ، لأنه سيكون عليك استخراج الأرقام بطريقة ما وتحويلها مرة أخرى إلى أرقام حتى يتسنى لك الوصول إليها.

لحسن الحظ، فجافاسكربت تتوفر على نوع بيانات مخصص لتخزين سلاسل من القيم، يدعى هذا النوع بالمصفوفة ويكتب على شكل قائمة من القيم بين معقوفتين مفصولة بفواصل.

var listOfNumbers = [2, 3, 5, 7, 11];
console.log(listOfNumbers[1]);
// → 3
console.log(listOfNumbers[1 - 1]);
// → 2
 


ملاحظة لا علاقة لها بترجمة الكتاب : صديقي من يقوم بترجمة هذا الجزء لقد قمت بأخد الجزء على عاتقي لترجمته و هذا ما اتفقنا عليه في المجتمع لهذا اذا اردت في متابعة الجزء معي أرجو أن تقوم بالتحدث معي لكي نقوم بالتنسيق فيما بيننا و لاتضيع جهودنا سدى لأنني قمت بترجمة هذه المقدمة ثم وجدت أنك قد ترجمتها مسبقا . انا اسمي omar sh


الترميز الذي يمكن من خلاله الوصول إلى داخل المصفوفة يمكن أن يكون باستخدام الأقواس المربعة []، زوج من الأقواس المربعة مباشرة بعد الصيغة (اسم المصفوفة) مع صيغة أخرى داخل هذه الأقواس وهي رقم العنصر علماً أن البحث عن العنصر يبدأ من اليسار لليمين حتى يجد العنصر الذي تبحث عنه من خلال الرقم الذي تضعه الأقواس.


العنصر الأول من المصفوفة هو الصفر و ليس واحد، وبالتالي سيكون العنصر الأول من المصفوفة يمكن قراءته هكذا listOfNumbers[0] ، اذا لم تكن تملك خلفية برمجية هذا لن يكون مقنعاً بالنسبة لك لكن الصفر سيبقى قاعدة أساسية في علم البرمجة و ستتعود عليه مع مرور الوقت.

الخصائص :

رأينا مسبقاً بعض الشبهات في بعص الصيغ البرمجية مثل mystring.length لكي تحصل على طول السلسة ) و (Math.max) لتحصل على القيمة الأعظمية في الأمثلة الماضية. و قد كانت هذه الصيغ لكي تقوم بالدخول إلى خاصية تابعة لقيمة معينة. في الحالة الأولى مثلاً كانت من أجل الدخول إلى خاصية ال (length) في قيمة السلسة myString. و الحالة الثانية ستقوم بالدخول إلى خاصية اسمها max في الكائن المسمى Math و الذي يحتوي على العديد من الدوال الرياضية.

تقريباً كل قيم الجافا سكربت تملك خصائص. إلا الاستثناء null و undefined فإذا حاولت الولوج إلى خصائص إحدى هذه القيم ستحصل على خطأ برمجي، حيث أن null و undefined تعني لا شيء

null.length;
// → TypeError: Cannot read property 'length' of null

أكثر طريقتين شائعتين للولوج إلى الخصائص في الجافا سكربت تكون من خلال النقط أو من خلال الأقواس المربعة حيث يمكنك أن تكتب [value[x و يمكنك أن تكتب value.x و بهذا يمكنك الولوج إلى خاصية العنصر value، مع العلم أن ما بعد النقطة يجب أن يكون اسم متغير مُعرَف سابقاً و موجود.

اذاً إذا كنت تعرف أن الخاصية المهتم بإستدعائها هيlength تقول value.length و اذا أردت أن تنسخ اسم الخاصية بحسب القيمة الموجودة في المتغير i تقول [value[i. و لأن أسماء الخواص ممكن أن تكون أي سلسلة (string) اذا أردت الوصول إلى خاصية اسمها "2" او خاصية اسمها “john Doe” لابد أن تستخدم الأقواس المربعة [value[2 و ["value[“john Doe لإنك حتماً لن تستطيع استخدام طريقة النقطة مع الأرقام أو مع السلاسل التي يرافقها فراغات (spaces) كما أن "2" و "“john Doe ليست أسماء متغيرات صحيحة(أي أنها غير موجودة افترضياً في لغة حافا سكربت) لهذا لا يمكن الولوج إليهما من خلال ترميز النقطة .

العناصر في المصفوفة تخزن في خواص، حيث أن أسماء هذه الخواص هم أرقام و عادة نحتاج إلى الحصول عليهم من خلال متغير، علينا أن نستخدم القوسين المربعين للولوج إليهم. أما بالعودة إلى خاصية length (خاصية لمعرفة طول السلاسل و المصفوفات) التي تخبرنا كم عنصر موجود في المصفوفة ، و بما أن length هي اسم متغير صحيح موجود في الجافا سكربت و بما أننا نعلمها مسبقاً بالتالي يمكننا الولوج إلى هذه الخاصية من خلال array.length ، طبعا يمكننا الولوج إليها من خلال الأقواس ["array[“length لكن لا نستخدم هذه الطريقة لأنها طويلة على عكس الطريقة الأولى.

Methods_الدوال :

السلاسل و المصفوفات تحتوي بالإضافة على خاصية معرفة الطول (length) عدد من الخصائص الأخرى التي يمكن من خلالها الإشارة إلى قيم الدالة.

var doh = "Doh";
console.log(typeof doh.toUpperCase);
// → function
console.log(doh.toUpperCase());
// → DOH

كل سلسلة (string) تملك خاصية toUpperCaseلة التي من خلالها تقوم بإرجاع نسخة من السلسة محوِّ كل الأحرف الصغيرة إلى أحرف كبيرة. هناك أيضاً خاصية toLowerCase يمكنك أن تحزر بنفسك ماذا تفعل. المثير للاهتمام، أن خاصية toUpperCase لا تأخذ أيِ قيم لكنها تستطيع الوصول إلى السلسة "Doh" ، هذه الخاصية سنقوم بشرحها بشكل تفصيلي الفصل السادس, الخواص التي تحتوي على دوال نطلق عليها (methods) حيث أن toUpperCase هي method للسلاسل. هذا المثال يوضح بعض ال methods التي تحتويها كائن المصفوفة :

var mack = [];
mack.push("Mack");
mack.push("the", "Knife");
console.log(mack);
// → ["Mack", "the", "Knife"]
console.log(mack.join(" "));
// → Mack the Knife
console.log(mack.pop());
// → Knife
console.log(mack);
// → ["Mack", "the"]
دالة ال push تقوم بإضافة قيمة إلى نهاية المصفوفة. ال pop تقوم بالعكس تماماً حيث تقوم بحذف آخر عنصر في المصفوفة و ترجعها. مصفوفة السلاسل يمكن أن تجمع في سلسلة واحدة من خلال الدالة join. العبارة التي تعطى لـ join تُحدِد الحرف الذي سيتم فصل الكلمات عند الوقوف عنده. مثلا : (“ “)join سيتم فصل الكلمات كل ما وجِد البرنامجspace . **Objects_الكائنات**: بالعودة إلى قصة السنجاب الفروي. يمكن تسجيل مجموعة من التسجيلات والمدخلات اليومية من خلال مصفوفة. لكن هذه التسجيلات والمدخلات لا تحتوي على سلاسل و أرقام فحسب. إنما كل تسجيل يحتاج إلى يحتاج إلى تخزين مجموعة من النشاطات و الأعداد البوليانية (1و0) التي تحدد فيما إذا جاك قد تحول إلى سنجاب أو لا. إذاً سنقوم بتجميع هذه القيم مع بعضها البعض في قيمة واحدة و من ثم نضع هذه القيم المجمعة في مصفوفة من المدخلات. القيم من نوع كائن (object) هي مجموعات كيفية (اعتباطية) من الخصائص ، و من الممكن إضافة أو حذف تلك الخصائص كما نريد. بالطبع هناك طريقة واحد لإنشاء كائن و هي من خلال استخدام القواس {}
var day1 = {
  squirrel: false,
  events: ["work", "touched tree", "pizza", "running",
           "television"]
};
console.log(day1.squirrel);
// → false
console.log(day1.wolf);
// → undefined
day1.wolf = false;
console.log(day1.wolf);
// → false
داخل هذه الأقواس، نستطيع إعطاء مجموعة من الخصائص وبين كل خاصية وخاصية هناك فاصلة، وكل خاصية مكتوبة كاسم وملحوقة بنقطتين ثم الصيغة التي تعطي لهذه الخاصية القيمة الخاصة بها. طبعاً لا حاجة للفراغات والأسطر الزائدة إنما هي موجودة في المثال السابق فقط لتجعل عملية القراءة أسهل وأسرع. الخصائص التي أسمائها ليست متغيرات وأرقام صحيحة يجب أن تكون موضوعة ضمن علامتي تنصيص.
var descriptions = {
  work: "Went to work",
  "touched tree": "Touched a tree"
};
هذا يعني أن الأقواس المعكوفة {} لها معنيان في لغة الجافا سكربت، الأول إن كانت في البداية فهي تعني أنها ستأخذ مجموعة من الجمل البرمجية و في أي موضع آخر لها فإنها تعني أنها ستصف كائن (object). لحسن الحظ هذه الأقواس لا تُستخدَم عادة لنبدأ بها كتابتنا لغة جافا سكربت في البرامج الاعتيادية، لهذا لن تجد الكثير من الغموض أو الصعوبة في استخدام هذه الأقواس. قراءة خاصية ليست موجودة ستنتج قيمة (undefined)، والتي تحدث عندما نحاول قراءة الخاصية wolf في المثال السابق. من الممكن أن تعين قيمة لخاصية ما باستخدام اشارة =، سيكون هذا كفيلاً بتغيير قيمة الخاصية في الكائن اذا كانت الخاصية موجوداً مسبقاً أو إنشاء خاصية جديدة في الكائن اذا كانت الخاصية ليست موجودة.
بالعودة إلى موديل الأرجل المترابطة الخاصة بالمتغيرات، ارتباط الخصائص هو نفسه. حيث أنهم يربطون القيم، وقد تحمل الخصائص المتغيرات الأخرى نفس القيم، يمكن أن تفكر بالكائنات كأخطبوط مع عدد من الأرجل، كل من هذه الأرجل لها اسم منقوش عليها.
![الويريسويرل](http://eloquentjavascript.net/img/octopus-object.jpg)
عامل الـ delete يقوم بقطع رجل من أرجل الأخطبوط. حيث أنه عامل أحادي حينما يتم تطبيقه على إحدى الخصائص في الكائن، سيقوم بحذف الخاصية المطلوبة من الكائن. هذا ليس شائعاً، لكنه ممكن. ملاحظة: ستتعرف قريباً على معنى العنصر الأحادي و العنصر الثنائي.
var anObject = {left: 1, right: 2};
console.log(anObject.left);
// → 1
delete anObject.left;
console.log(anObject.left);
// → undefined
console.log("left" in anObject);
// → false
console.log("right" in anObject);
// → true
العامل الثنائي in، حينما يتم تطبيقه على سلسلة وكائن سيقوم بإرجاع قيمة بوليانية (0 أو 1) التي تحدد فيما إذا كان الكائن يحتوي على تلك الخاصية أو لا. الفرق بين تعيين الخاصية إلى undefined وحذفها هو أنه في الحالة سيحتوي الكائن على تلك الخاصية، لكن إن بحثت في تلك الخاصية ستجدها فارغة أي لا تحوي أيِ قيم، أما الحالة الثانية فإن الخاصية لم تعد موجودة أصلاً في الكائن وبالتالي فإن العامل in سيقوم بإرجاع 0 أو false بالعودة إلى العامل الأحادي والعامل الثنائي ما الفرق بينهما: الفرق بسيط جداً حيث أن العامل الأول لا يأخذ إلا معامل واحد قد تجدها قبل أو بعد الصيغة مثل .
Delete x نلاحظ أن delete لا تأخذ إلا معامل واحد فقط. يمكنك أن تعرف بنفسك ما معنى العامل الثنائي. المصفوفات هي نوع من الكائنات التي تخزن سلسلة من الأشياء، فإذا كتبت في بيئة الجافا سكربت هذا الجملة typeof[1,2] ستلاحظ أن البرنامج سيرجع لك object وبالتالي فإن الجافا سكربت تعتبر المصفوفة نوع من أنواع الكائنات. يمكنك أن ترى الصورة في الأسفل كيف أن أرجل الأخطبوط مرتبة في صف واحد و مرقمة
!)]arr]uu.jpg)
var journal = [
  {events: ["work", "touched tree", "pizza",
            "running", "television"],
   squirrel: false},
  {events: ["work", "ice cream", "cauliflower",
            "lasagna", "touched tree", "brushed teeth"],
   squirrel: false},
  {events: ["weekend", "cycling", "break",
            "peanuts", "beer"],
   squirrel: true},
  /* and so on... */
];