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


إبراهيم البحيصي

مقدمة

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

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

لتوضيح كيف من الممكن أن تكون المصفوفات مهمة، لنفترض أننا نريد أن نحفظ أسماء المحيطات في متغيرات عدة، بحيث يكون لكل محيط المتغير الخاص به:

 

oceans.js
// Assign the five oceans to five variables

const ocean1 = "Pacific";

const ocean2 = "Atlantic";

const ocean3 = "Indian";

const ocean4 = "Arctic";

const ocean5 = "Antarctic";

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

باستخدام المصفوفات، نستطيع تبسيط الأمر.

oceans.js
// Assign the five oceans

let oceans = [

    "Pacific",

    "Atlantic",

    "Indian",

    "Arctic",

    "Antarctic",

];

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

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

// Print out the first item of the oceans array

oceans[0];

Output

Pacific

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

إنشاء مصفوفة

يوجد طريقتان لإنشاء المصفوفة في جافا سكريبت:

  1. التعريف اللفظي باستخدام الأقواس المعكوفة.
  2. التعريف بواسطة الباني (constructor) باستخدام كلمة new.

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

sharks.js
// Initialize array of shark species with array literal

let sharks = [

    "Hammerhead",

    "Great White",

    "Tiger",

];

الان نُعرف نفس المصفوفة باستخدام الباني وذلك بواسطة الجملة new Array() :

sharks.js
// Initialize array of shark species with array constructor

let sharks = new Array(

    "Hammerhead",

    "Great White",

    "Tiger",

);

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

نستطيع طباعة محتويات المصفوفة بكتابة المتغير الخاص بها مباشرة:

// Print out the entire sharks array

sharks;

Output

[ 'Hammerhead', 'Great White', 'Tiger' ]

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

// Initialize array of mixed datatypes

let mixedData = [

    "String",

    null,

    7,

    [

        "another",

        "array",

    ],

];

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

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

فهرسة المصفوفات

إذا تعاملت مسبقاً مع النصوص والفهرسة في الجافا سكريبت، ستكون مُلمًا بمفهوم فهرسة المصفوفات، حيث أن النص يُعتبر شبيهًا بالمصفوفة.

لا تحتوي المصفوفات على عناصر مزدوجة على شكل اسم/قيمة، وبدلا من ذلك، فإن المصفوفات تُفهرس بقيم عددية تبدأ من القيمة 0. المثال التالي ينشئ مصفوفة باسم seaCreatures:

seacreatures.js
let seaCreatures = [

    "octopus",

    "squid",

    "shark",

    "seahorse",

    "starfish",

];

الجدول التالي يُفصل كيف يتم فهرسة كل عنصر في المصفوفة بقيمة عددية ابتداءً من 0:

octopus squid shark seahorse starfish
0 1 2 3 4

العنصر الأول في المصفوفة هو octopus ومُفهرس في الموقع 0 من المصفوفة، والعنصر الأخير هو starfish ومُفهرس في الموقع 4. تبدأ الفهرسة من 0، وهذا يتضارب مع طبيعتنا الفطرية ببدء العد من القيمة 1، لذلك نحتاج لأخذ الاحتياط وأن نتذكر هذه النقطة دائما حتى تصبح طبيعية.

نستطيع أن نحصل على عدد العناصر في المصفوفة باستخدام الخاصية length:

seaCreatures.length;

Output

5

على الرغم من أن الفهارس الخاصة بالمصفوفة seaCreatuers تبدأ من 0 إلى 4، فإن الخاصية length سوف تُرجع العدد الفعلي للعناصر الموجودة في المصفوفة.

إذا أردنا معرفة رقم الفهرس لعنصر معين في المصفوفة، وليكن مثلا seahorse، نستطيع أن نستخدم لذلك الوظيفة indexOf() :

seaCreatures.indexOf("seahorse");

Output

3

إذا لم تحتوي المصفوفة على العنصر الذي نريده، فلن نحصل على رقم فهرس لعنصر غير موجود، وفي هذه الحالة، فإن الوظيفة سترجع لنا القيمة -1 كما في المثال التالي:

seaCreatures.indexOf("cuttlefish");

Output

-1

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

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

يتم الوصول لعنصر في مصفوفة جافا سكريبت بواسطة الإشارة لرقم الفهرس للعنصر بين قوسين معكوفين:

seaCreatures[1];

Output

squid

نعلم أن الرقم 0 سيعيد لنا دائما العنصر الأول في المصفوفة. كذلك نستطيع إيجاد العنصر الأخير في المصفوفة بواسطة إجراء عملية طرح قيمة 1 من قيمة الخاصية length للمصفوفة، والإشارة لناتج هذه العملية كرقم فهرس للعنصر الأخير كما هو موضح في المثال التالي:

const lastIndex = seaCreatures.length - 1;



seaCreatures[lastIndex];

Output

starfish

محاولة الوصول لعنصر غير موجود سيعيد لنا undefined:

seaCreatures[10];

Output

undefined

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

let nestedArray = [

    [

        "salmon",

        "halibut",

    ],

    [

        "coral",

        "reef",

    ]

];



nestedArray[1][0];

Output

coral

في المثال السابق، قمنا بالوصول للعنصر coral بالإشارة لرقم الفهرس الذي يحتوي المصفوفة الداخلية وهو 1، ثم أشرنا للفهرس الذي يحتوي على العنصر في المصفوفة الداخلية وهو 0.

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

في المتغير seaCreatuers يوجد لدينا 5 عناصر بأرقام فهراس تبدأ من 0 الى 4. إذا أردنا أن نُضيف عنصر جديد لهذه المصفوفة، فيمكننا أن نقوم بذلك بإعطاء قيمة للفهرس التالي الذي يلي اخر فهرس:

seaCreatures[5] = "whale";



seaCreatures;

Output

[ 'octopus',

    'squid',

    'shark',

    'seahorse',

    'starfish',

    'whale' ]

إذا قمنا بإضافة عنصر وتجاهلنا قيمة الفهرس التالي ووضعنا بدلا منه فهرس بقيمة 7 مثلا، فإن ذلك يؤدي لإضافة عنصر غير مُعرف (undefined) للمصفوفة كما في المثال التالي:

seaCreatures[7] = "pufferfish";



seaCreatures;

Output

[ 'octopus',

    'squid',

    'shark',

    'seahorse',

    'starfish',

    'whale',

    ,

    'pufferfish' ]

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

// Append lobster to the end of the seaCreatures array

seaCreatures.push("lobster");



seaCreatures;

Output

[ 'octopus',

    'squid',

    'shark',

    'seahorse',

    'starfish',

    ,

    'whale',

    'pufferfish',

    'lobster' ]

على العكس تماما من الوظيفة push()، فإن الوظيفة unshift() تقوم بإضافة العنصر في بداية المصفوفة:

// Append dragonfish to the beginning of the seaCreatures array

seaCreatures.unshift("dragonfish");



seaCreatures;

Output

[ 'dragonfish',

    'octopus',

    'squid',

    'shark',

    'seahorse',

    'starfish',

    'whale',

    ,

    'pufferfish',

    'lobster' ]

باستخدام الوظيفتين السابقتين، ستكون لديك المقدرة على إضافة عناصر جديدة للمصفوفة إما في بدايتها، أو نهايتها.

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

لإزالة عنصر معين من مصفوفة، نستخدم الوظيفة splice().

في المصفوفة seaCreatuers قمنا بإضافة عنصر غير مُعرف وليس له قيمة، ولإزالته نقوم بالتالي:

seaCreatures.splice(7, 1);



seaCreatures;

Output

[ 'dragonfish',

    'octopus',

    'squid',

    'shark',

    'seahorse',

    'starfish',

    'whale',

    'pufferfish',

    'lobster' ]

في الوظيفة splice()، المُعامل الأول يشير لرقم الفهرس الذي سنبدأ بالإزالة من عنده (في هذه الحالة 7)، والمُعامل الثاني يشير لعدد العناصر التي نرغب بإزالتها (في حالتنا سيكون 1 حيث أننا نرغب بإزالة عنصر واحد).

الوظيفة splice() ستؤثر على المتغير الأصلي. لذلك، إذا أردنا أن نحافظ على المصفوفة الأصلية دون تغيير، نستخدم الوظيفة slice() ونعطي القيمة الناتجة عنها لمتغير جديد.

let newArray = slice(7, 1);

الوظيفة pop() ستزيل العنصر الأخير من المصفوفة:

// Remove the last item from the seaCreatures array

seaCreatures.pop();



seaCreatures;

Output

[ 'dragonfish',

    'octopus',

    'squid',

    'shark',

    'seahorse',

    'starfish',

    'whale',

    'pufferfish' ]

العنصر lobster أُزيل من المصفوفة لأنه العنصر الأخير، ولإزالة العنصر الأول في المصفوفة، نستخدم الوظيفة shift():

// Remove the first item from the seaCreatures array

seaCreatures.shift();



seaCreatures;

Output

[ 'octopus',

    'squid',

    'shark',

    'seahorse',

    'starfish',

    'whale',

    'pufferfish' ]

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

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

نستطيع تغيير أي قيمة عنصر في المصفوفة وذلك بإعطاء القيمة الجديدة للعنصر باستخدام عملية المساواة، كما نفعل تماما عند التعامل مع المتغيرات العادية:

// Assign manatee to the first item in the seaCreatures array

seaCreatures[0] = "manatee";



seaCreatures;

Output

[ 'manatee',

    'squid',

    'shark',

    'seahorse',

    'starfish',

    'whale',

    'pufferfish' ]

طريقة أخرى لتغيير قيمة العنصر باستخدام الوظيفة splice() وذلك بإضافة مُعامل جديد. فمثلا، إذا أردنا تغيير قيمة العنصر seahorse والذي يقع في الفهرس 3، نستطيع إزالته وإضافة قيمة جديدة بدلا منه:

// Replace seahorse with sea lion using splice method

seaCreatures.splice(3, 1, "sea lion");



seaCreatures();

Output

[ 'manatee',

    'squid',

    'shark',

    'sea lion',

    'starfish',

    'whale',

    'pufferfish' ]

في المثال السابق، قمنا بإزالة العنصر seahorse من المصفوفة، ووضعنا بدلا منه القيمة sea lion في نفس الفهرس 3.

حلقة التكرار خلال المصفوفة

نستطيع المرور على عناصر المصفوفة من خلال حلقة تكرار for وذلك بالاستفادة من خاصية length. في المثال التالي، نُنشئ مصفوفة باسم shellfish ونطبع رقم كل فهرس فيها بالإضافة إلى قيمة العنصر المرتبط بالفهرس:

// Create an array of shellfish species

let shellfish = [

    "oyster",

    "shrimp",

    "clam",

    "mussel",

];



// Loop through the length of the array

for (let i = 0; i < shellfish.length; i++) {

  console.log(i, shellfish[i]);

}

Output

0 'oyster'

1 'shrimp'

2 'clam'

3 'mussel'

نستطيع أيضا استخدام حلقة التكرار for…of وهي خاصية جديدة في الجافا سكريبت:

// Create an array of aquatic mammals

let mammals = [

    "dolphin",

    "whale",

    "manatee",

];



// Loop through each mammal

for (let mammal of mammals) {

    console.log(mammal);

}

Output

dolphin

whale

manatee

حلقة التكرار for…of لا تقوم باستخدام رقم الفهرس للعناصر في المصفوفة، ولكنها بشكل عام طريقة أبسط وأكثر اختصارا للمرور على المصفوفة من خلال حلقة التكرار.

استخدام حلقات التكرار مفيد بشكل كبير في طباعة قيم عناصر المصفوفة وهو يشبه عرض العناصر من قاعدة بيانات خلال موقع الكتروني.

خاتمة

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

 

ترجمة -وبتصرّف- للمقال Understanding Arrays in JavaScript لصاحبه Tania Rascia

حقوق الصورة البارزة محفوظة لـ Freepik



1 شخص أعجب بهذا


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


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



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن