اذهب إلى المحتوى

المصفوفات في جافا سكريبت


ابراهيم الخضور

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

ننصحك قبل المتابعة في قراءة هذا المقال بالاطلاع على بعض المقالات السابقة مثل:

  1. أساسيات علوم الحاسب.
  2. أساسيات HTML.
  3. أساسيات عمل CSS

ما هي المصفوفات؟

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

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

وكما فعلنا في مقالات أخرى سنتدرب على أساسيات التعامل مع المصفوفات باستخدام طرفية جافا سكريبت في المتصفح والتي يمكنك الوصول لها من خلال النقر على مفاتيح (Ctrl + Shift+ K في فايرفكس).

إنشاء المصفوفات

تتكون المصفوفة من قوسين مربعين وعناصر تفصل بينها فاصلة ,.

  1. افترض أنك تريد تخزين لائحة التسوق التالية في مصفوفة، أنشأ هذه المصفوفة بنسخ ولصق الشيفرة التالية في الطرفية:
const shopping = ["bread", "milk", "cheese", "hummus", "noodles"];
console.log(shopping);
  1. إن كل عناصر المصفوفة السابقة هي عناصر نصية، لكن بإمكانك تخزين أنواع مختلفة من البيانات مثل الأعداد والسلاسل النصية والكائنات وحتى مصفوفات أخرى. كما يمكن استخدام أنواع مختلفة في المصفوفة نفسها، فلا ضرورة لإلزام أنفسنا بإنشاء مصفوفة لتخزين الأعداد وأخرى للنصوص. إليك مثالًا:
const sequence = [1, 1, 2, 3, 5, 8, 13];
const random = ["tree", 795, [0, 1, 2]];
  1. جرب إنشاء بعض المصفوفات قبل المتابعة.

إيجاد طول مصفوفة

بإمكانك إيجاد طول مصفوفة (عدد العناصر التي تضمها) بنفس طريقة إيجاد عدد المحارف في سلسلة نصية باستخدام الخاصية ()length:

const shopping = ["bread", "milk", "cheese", "hummus", "noodles"];
console.log(shopping.length); // 5

الوصول إلى عناصر مصفوفة وتعديلها

  1. تُرقم عناصر المصفوفة ابتداءً من الصفر ويُدعى هذا الرقم دليل العنصر item index. وهكذا سيكون دليل العنصر الأول هو 0 والثاني 1 وهكذا. وللوصول إلى عنصر معين في مصفوفة ضع اسم المصفوفة يليها قوسين مربعين ضمنهما دليل العنصر أي بنفس الطريقة التي تصل فيها إلى محرف في سلسلة نصية:
const shopping = ["bread", "milk", "cheese", "hummus", "noodles"];
console.log(shopping[0]);
// returns "bread"
  1. بالإمكان أيضًا تعديل عنصر في المصفوفة بإسناد قيمة جديدة إلى العنصر المطلوب:
const shopping = ["bread", "milk", "cheese", "hummus", "noodles"];
shopping[0] = "tahini";
console.log(shopping);
// shopping will now return [ "tahini", "milk", "cheese", "hummus", "noodles" ]

ملاحظة: تذكر أن العد أو الفهرسة في جافا سكريبت تبدأ من 0 وليس من 1.

  1. تُدعى المصفوفة ضمن مصفوفة بالمصفوفة متعددة الأبعاد، ويمكن الوصول إلى عنصر في مصفوفة موجودة ضمن مصفوفة أخرى بكتاب اسم المصفوفة الخارجية يليها زوجين من الأقواس المربعة يضم الأول دليل المصفوفة الداخلية ضمن المصفوفة الخارجية وفي الثاني دليل العنصر المطلوب في المصفوفة الداخلية. فلو أردت الوصول إلى أحد عناصر المصفوفة التي دليلها 2 (العنصر الثالث) ضمن المصفوفة random يمكنك إنجاز الأمر كالتالي:
const random = ["tree", 795, [0, 1, 2]];
random[2][2];
  1. جرّب أن تعدّل على عناصر المصفوفات التي أنشأتها قبل المتابعة.

إيجاد دليل العناصر في مصفوفة

إن لم تكن تعرف دليل العنصر، استخدم التابع ()indexOf الذي يأخذ العنصر وسيطًا له ويعيد دليله إن كان موجودًا أو 1- إن لم يجده.

const birds = ["Parrot", "Falcon", "Owl"];
console.log(birds.indexOf("Owl")); //  2
console.log(birds.indexOf("Rabbit")); // -1

إضافة عنصر إلى مصفوفة

ﻹضافة عنصر أو أكثر إلى نهاية المصفوفة، نستخدم التابع ()push وعليك حينها التأكد من إضافة عنصر أو آخر إلى نهاية المصفوفة.

const cities = ["Manchester", "Liverpool"];
cities.push("Cardiff");
console.log(cities); // [ "Manchester", "Liverpool", "Cardiff" ]
cities.push("Bradford", "Brighton");
console.log(cities); // [ "Manchester", "Liverpool", "Cardiff", "Bradford", "Brighton" ]

يعيد التابع طول المصفوفة الجديد عند نجاح العملية، وبإمكانك أيضًا تخزين طول المصفوفة الجديد بإسناد التابع إلى متغير كالتالي:

const cities = ["Manchester", "Liverpool"];
const newLength = cities.push("Bristol");
console.log(cities); // [ "Manchester", "Liverpool", "Bristol" ]
console.log(newLength); // 3

وﻹضافة عناصر إلى بداية مصفوفة، استخدم التايع ()unshift:

const cities = ["Manchester", "Liverpool"];
cities.unshift("Edinburgh");
console.log(cities); // [ "Edinburgh", "Manchester", "Liverpool" ]

إزالة عناصر من مصفوفة

ﻹزالة العنصر اﻷخير من مصفوفة، استخدم التابع ()pop:

const cities = ["Manchester", "Liverpool"];
cities.pop();
console.log(cities); // [ "Manchester" ]

يعيد هذا التابع العنصر الذي أزيل من المصفوفة، ولكي تخزن هذا العنصر في متغيّر، يمكنك اتباع الطريقة التالية:

const cities = ["Manchester", "Liverpool"];
const removedCity = cities.pop();
console.log(removedCity); // "Liverpool"

وﻹزالة العنصر اﻷول من مصفوفة استخدم التابع ()shift:

const cities = ["Manchester", "Liverpool"];
cities.shift();
console.log(cities); // [ "Liverpool" ]

وإن كنت تعلم دليل العنصر بإمكانك إزالته من المصفوفة باستخدام التابع ()splice:

const cities = ["Manchester", "Liverpool", "Edinburgh", "Carlisle"];
const index = cities.indexOf("Liverpool");
if (index !== -1) {
  cities.splice(index, 1);
}
console.log(cities); // [ "Manchester", "Edinburgh", "Carlisle" ]

يحدد الوسيط الأول للتابع ()splice دليل العنصر الذي تبدأ عنده إزالة العناصر، ويحدد الوسيط الثاني عدد العناصر التي يجب إزالتها، وبالتالي بإمكانك استخدامه ﻹزالة عدة عناصر:

const cities = ["Manchester", "Liverpool", "Edinburgh", "Carlisle"];
const index = cities.indexOf("Liverpool");
if (index !== -1) {
  cities.splice(index, 2);
}
console.log(cities); // [ "Manchester", "Carlisle" ]

الوصول إلى كل العناصر

قد تحتاج أحيانًا الوصول إلى كل عنصر من عناصر مصفوفة، عندها يمكنك استخدام الحلقة for...of:

const birds = ["Parrot", "Falcon", "Owl"];

for (const bird of birds) {
  console.log(bird);
}

وقد تضطر أحيانًا إلى تنفيذ عملية ما على كل عنصر من عناصر مصفوفة للحصول على مصفوفة جديدة مختلفة عن اﻷصل. استخدم لهذه الغاية التابع ()map. يوضح المثال التالي كيفية مضاعفة جميع أعداد مصفوفة عددية:

function double(number) {
  return number * 2;
}
const numbers = [5, 2, 7, 6];
const doubled = numbers.map(double);
console.log(doubled); // [ 10, 4, 14, 12 ]

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

function isLong(city) {
  return city.length > 8;
}
const cities = ["London", "Liverpool", "Totnes", "Edinburgh"];
const longer = cities.filter(isLong);
console.log(longer); // [ "Liverpool", "Edinburgh" ]

وكذلك يستدعي التابع ()filterدالة لاختبار كل عنصر من عناصر المصفوفة فإن أعادت القيمة true يُضاف العنصر إلى المصفوفة الجديدة ثم يعيد هذه المصفوفة في النهاية.

التحويل بين المصفوفات والسلاسل النصية

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

  1. أنشئ السلسلة النصية التالية في طرفية جافا سكربت ;"const data = "Manchester,London,Liverpool,Birmingham,Leeds,Carlisle
  2. افصل السلسلة عند المحرف ,:
   const cities = data.split(",");
   cities;
  1. حاول حساب طول المصفوفة الجديدة واستخلص بعض عناصرها:
   cities.length;
   cities[0]; // the first item in the array
   cities[1]; // the second item in the array
   cities[cities.length - 1]; // the last item in the array
  1. بإمكانك عكس العملية باستخدام التابع ()join:
   const commaSeparated = cities.join(",");
   commaSeparated;
  1. كما يمكن تحويل المصفوفة إلى سلسلة نصية باستخدام التابع ()toString الذي يعده البعض أبسط من ()join لأنه يأخذ معاملًا وحيدًا، لكنه أكثر محدودية فلا يمكنه الفصل سوى عند المحرف , على عكس ()join الذي يمكن أن تحدد فيه أكثر من محرف لفصل السلاسل.
   const dogNames = ["Rocket", "Flash", "Bella", "Slugger"];
   dogNames.toString(); // Rocket,Flash,Bella,Slugger

تطبيق عملي: طباعة قائمة منتجات

بالعودة إلى مثالنا السابق عن قائمة المنتجات وأسعارها التي نريد إدراجها في فاتورة ثم نحسب إجمالي الفاتورة ونطبعها في اﻷسفل. ستجد في المحرر التفاعلي التالي مجموعة من التعليقات المرقمة، ويحدد كل تعليق مكانًا لكتابة شيفرة معينة:

  1. تحت التعليق number 1// ستجد عددًا من السلاسل النصية التي تضم كلا منها اسم المنتج وسعره ويفصل بينهما فاصلة. والمطلوب منك تحويلها إلى مصفوفة وتخزينها ضمن المتغيّر products
  2. أنشئ حلقة for...of تحت التعليق number 2// كي تمر على جميع عناصر المصفوفة السابقة.
  3. اكتب تحت التعليق number 3// شيفرة لفصل عناصر المصفوفة السابقة () إلى عنصرين يضم اﻷول الاسم والثاني السعر. إن لم تكن متأكدًا من طريقة تنفيذ اﻷمر راجع مقال [توابع جافا سكريبت اﻷصلية للتعامل مع النصوص]()، أو عد إلى فقرة التحويل بين المصفوفات والسلاسل النصية التي عرضناها قبل قليل.
  4. ويجب عليك أيضًا أن تحوّل السعر في السطر السابق من نص إلى عدد. يمكنك العودة إلى مقال التعامل مع النصوص في جافا سكريبت كي تتذكر آلية تنفيذ اﻷمر.
  5. ستجد متغرًا باسم totalوقد أسندت إليه القيمة 0. نطلب إليك أن تضيف سطرًا ضمن الحلقلة الموجودة أسفل التعليق number 4// ﻹضاف سعر العنصر الحالي إلى قيمة المتغير total عند كل تكرار للحلقة حتى نحصل في النهاية على إجمالي السعر أسفل الفاتورة، وقد تحتاج إلى استخدام عامل إسناد مناسب.
  6. غيّر السطر أسفل التعليق number 5// لتصبح قيمة المتغيّر مطابقة للسلسلة "العنصر الحالي — سعر العنصر الحالي$" مثل "Shoes — $23.99" عند كل تكرار كي تُطبع المعلومات الصحيحة لكل منتج ضمن الفاتورة. وتُنفّضذ العملية بضم بسيط لسلسلتين نصيتين.
  7. أضف القوس { أسفل التعليق number 6// ﻹنهاء حلقة for...of.

See the Pen js-array-1 by Hsoub Academy (@HsoubAcademy) on CodePen.

تطبيق عملي: نتائج البحث الخمسة الأولى

يظهر استخدام مهم للتابعين ()push و ()pop عندما تريد أن تحدّث سجلًا لعناصر نشطة في تطبيق ويب، كأن يكون لديك تطبيق يعرض رسومًا متحركة ويضم عددًا كبيرًا من الكائنات مثل الخلفية وعناصر اخرى وتريد لسبب أو ﻵخر عرض 50 كائنًا فقط معًا. فعند إضافة عناصر جديدة لمصفوفة الكائنات تّحذف عناصر أقدم ليبقى عدد الكائنات المعروضة 50. في تطبيقنا هذا سنبسط اﻷمر أكثر، إذ سنفترض وجود محرك بحث وهمي يضم صندوق بحث، ومن المفترض عرض قائمة بآخر خمس عمليات بحث عند إدخال أي شيء في صندوق البحث. وعند تجاوز عمليات البحث 5 عمليات تُحذف العملية اﻷقدم وتضاف العملية الجديدة كي يبقى عدد عناصر القائمة 5. ملاحظة: قد تكون قادرًا في تطبيقات البحث الفعلية على النقر على زر ما لاستعادة جمع عمليات البحث التي جرت وطريقة لعرض كل النتائج. ﻹنجاز اﻷمر:

  1. أضف سطرًا تحت التعليق number 1// الذي يضيف عملية البحث المدخلة مؤخرًا إلى بداية المصفوفة، ويمكن الحصول على هذه القيمة من خلال اﻷمر searchInput.vlue.
  2. أضف سطرًا تحت التعليق number 2// كي يزيل العنصر الموجود في آخر المصفوفة حاليًا.

الخلاصة

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

ترجمة -وبتصرف- للمقال Arrays

اقرأ أيضًا

 


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...