المسارات
/
Bash
Bash
/
المنهج
/
المصفوفات
ال

المصفوفات في Bash

{zero: "لا توجد تمارين", one: "1 تمرين", two: "تمرينان", few: "%{count} تمارين", many: "%{count} تمرينًا", other: "%{count} تمرين"}

نبذة عن المصفوفات

يوفّر Bash نوعين من المعاملات: القيم «القياسية» والمصفوفات. يمكن أن تكون القيمة القياسية سلسلة نصية أو عددًا، وهي تمثّل «شيئًا» واحدًا.

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

هناك نوعان من المصفوفات:

  • المصفوفات المفهرسة رقميًا تربط مفتاحًا من نوع العدد الصحيح بقيمة من نوع السلسلة النصية. (قد تسمّيها لغات أخرى «قائمة» أو «تسلسلًا».)
  • المصفوفات الترابطية تربط مفتاحًا من نوع السلسلة النصية بقيمة من نوع السلسلة النصية. (قد تسمّيها لغات أخرى «خريطة» أو «قاموسًا».)

ستغطّي الأقسام الأولى من هذه الوثيقة المصفوفات المفهرسة رقميًا (وسنسمّيها فيما بعد ببساطة «المصفوفات»). وستظهر تفاصيل المصفوفات الترابطية في النهاية.

Caution

تستطيع مصفوفات Bash تخزين القيم القياسية فقط. ولا توجد أي إمكانية لإنشاء مصفوفة ثنائية الأبعاد (مصفوفة من المصفوفات).

تعريف متغير مصفوفة وتهيئته

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

myarray=("one" "two" "three")

وكما هي الحال في كل إسناد لمتغير، لا يجوز وجود مسافات حول علامة المساواة.

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

بل إن مقدار الفراغات داخل الأقواس عشوائي تمامًا. يُسمح بأسطر جديدة، فاستخدم منها ما تشاء لتحسين قابلية القراءة.

myarray=(
    "first element"
    "second element"
    "this is the last element"
)

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

ويمكنك تهيئة «مصفوفة متفرقة» بتحديد الفهارس التي تحتاجها.

raindrops=([3]="Pling" [5]="Plang" [7]="Plong")
Note

للتذكير: فهارس المصفوفات تبدأ من الصفر. يُخرج هذا المقتطف "true":

myarray=("one" "two" "three")
[[ "${myarray[0]}" == "one" ]] && echo true || echo false

يمكنك استخدام الأمر declare (أو local داخل دالة) لتحديد أن متغيرًا ما سيحتفظ بمصفوفة.

declare -a myarray

والأسلوب الأكثر شيوعًا هو أن تسند قائمة بين قوسين هلاليين (فارغة ربما) لتهيئة المتغير.

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

كما رأيت في الملاحظة أعلاه، صيغة الوصول إلى عنصر من المصفوفة هي ${myarray[$index]}. ويُعطى الفهرس بين قوسين مربعين. والأقواس المعقوفة ضرورية.

Note

في المصفوفات المفهرسة رقميًا، يكون الفهرس تعبيرًا حسابيًا. يذكر دليل Bash:

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

وهذا يعني أن $ ليس ضروريًا في التوسيع «البسيط» للمتغيرات. ويمكنك الوصول إلى العناصر على هذا النحو، وهو أسهل قليلًا في القراءة:

i=5
echo "${myarray[i]}"
# ..............^

إذا لم يكن الفهرس المعطى موجودًا في المصفوفة، فإن نتيجة التوسيع تكون سلسلة نصية فارغة.

الإسناد إلى مصفوفة

لإسناد قيمة إلى عنصر معيّن من المصفوفة، استخدم هذه الصيغة:

myarray[10]="hello"

ول_إلحاق_ عنصر بمصفوفة، استخدم عامل الإسناد بالدمج += مع الأقواس الهلالية:

myarray+=("new element 1" "new element 2")

التكرار على عناصر المصفوفة

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

myarray=("one" "two" "three")
for value in "${myarray[@]}"; do
    echo "$value"
done

لاحظ الصيغة الخاصة لتوسيع المصفوفة: "${myarray[@]}" هذه الصيغة من توسيع المعاملات تُوسّع قيم المصفوفة إلى كلمات منفصلة. وهي مكافئة إلى حد ما لـ:

for value in "${myarray[0]}" "${myarray[1]}" ... "${myarray[n]}"

تعمل صيغة "${myarray[@]}" مع المصفوفات المتفرقة، إذ تُوسّع إلى القيم المعرَّفة فقط.

هذا التوسيع الخاص، حيث يكون الفهرس علامة العطف (@)، لا يكون خاصًا إلا داخل علامات الاقتباس المزدوجة.

صيغ أخرى خاصة لتوسيع المعاملات

إليك بضعة أجزاء أخرى من الصيغة الخاصة التي نحتاجها للتكرار على مصفوفة. وهي موصوفة في الدليل ضمن توسيع معاملات الصدفة.

لمعرفة طول المصفوفة، استخدم ${#myarray[@]}، مع علامة # قبل الاسم. ويقصد بـ«طول» المصفوفة عدد العناصر فيها.

ولاستخراج قائمة فهارس المصفوفة، استخدم "${!myarray[@]}"، مع علامة ! قبل الاسم ووضع التوسيع بين علامات الاقتباس المزدوجة. وفي المصفوفات المفهرسة رقميًا، تُوسّع الفهارس بترتيب رقمي.

التكرار على فهارس المصفوفة

تحتاج أحيانًا إلى الفهرس بالإضافة إلى القيمة. وهناك أسلوبان لتحقيق ذلك.

  1. عندما تعرف أن الفهارس تشكّل تسلسلًا متواصلًا، يمكنك استخدام حلقة for حسابية.

    for ((i = 0; i < ${#myarray[@]}; i++)); do
        echo "$i -> ${myarray[i]}"
    done
    

    لاحظ صيغة ${#myarray[@]}، مع الحرف # قبل اسم المصفوفة. ولأن المصفوفات تستخدم فهرسة تبدأ من الصفر، فإن فهرس المصفوفة الأخير يقلّ بواحد عن طول المصفوفة.

  2. عندما تكون المصفوفة متفرقة، يمكنك استخدام هذه الصيغة:

    for index in "${!raindrops[@]}"; do
        echo "$index -> ${raindrops[index]}"
    done
    

    لاحظ صيغة ${!myarray[@]}، مع الحرف ! قبل اسم المصفوفة.

فحص المصفوفة

إذا أردت الاطلاع على محتوى مصفوفة، فاستخدم الأمر declare مع الخيار -p:

a=("the 'first' element"
   second
   third
   'the "last" element')
declare -p a

يُخرج هذا المحتوى مع اقتباس الصدفة القياسي.

declare -a a=([0]="the 'first' element" [1]="second" [2]="third" [3]="the \"last\" element")

المصفوفات الترابطية

للتذكير، تستخدم المصفوفات الترابطية السلاسل النصية كفهارس، لا الأعداد. وكل ما كُتب أعلاه ينطبق على المصفوفات الترابطية، لكن مع اختلافات صغيرة. وبصفة عامة، نستخدم مصطلح «مفتاح» لا «فهرس»، فالمصفوفات الترابطية تربط المفاتيح بالقيم.

تعريف مصفوفة ترابطية

على عكس المصفوفات، يجب تعريف المصفوفات الترابطية. استخدم الخيار -A مع declare (أو local داخل دالة):

declare -A mymap

myfunc() {
    local -A my_local_map
    # ...
}

تهيئة مصفوفة ترابطية

تُحدَّد أزواج المفتاح والقيمة داخل القائمة المحاطة بالقوسين الهلاليين:

mymap=([first]=foo [second]=bar [third]=baz)
declare -p mymap

وهذا يُخرج:

declare -A mymap=([second]="bar" [first]="foo" [third]="baz")
Note

انتبه إلى أن المصفوفات الترابطية غير مرتّبة.

يمكن أن يحدث التعريف والتهيئة في سطر واحد.

declare -A mymap=([first]=foo [second]=bar [third]=baz)

وفي إصدارات Bash الحديثة، يمكن أن تستخدم التهيئة قائمة (key value key value ...).

declare -A mymap=(first foo second bar third baz)

الوصول إلى القيم

تُستخدم الصيغة نفسها كما في السابق للوصول إلى العناصر: ${mymap[$key]}.

لا تُقيَّم مفاتيح المصفوفات الترابطية في سياق حسابي. بل تلزم صيغة توسيع المعاملات المعتادة.

الإسناد إلى مصفوفة ترابطية

يستخدم الإسناد الصيغة نفسها كما في السابق:

mymap[$key]="$value"

التكرار

يمكنك استخدام حلقة for value in "${mymap[@]}" للتكرار. لكنك تحتاج عادةً أيضًا إلى المفتاح إلى جانب القيمة.

استخدم صيغة "${!mymap[@]}" التي رأيناها أعلاه.

for key in "${!mymap[@]}"; do
    echo "$key -> ${mymap[$key]}"
done

وهذا يُخرج

second -> bar
first -> foo
third -> baz

وللتأكيد مرة أخرى، لا يوجد أي ترتيب للمفاتيح.

تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة