هل تعرف حقا ما هي المصفوفات؟

حيث أعمل ، أتوقع معرفة PHP و JavaScript من مطوري الويب. عند إجراء المقابلات ، وجدت أنه يكفي طرح سؤال واحد بسيط لمعرفة مدى فهم المطور للأدوات التي يستخدمها كل يوم. هذا السؤال هو:

ما هي أوجه التشابه والاختلاف بين المصفوفات في JavaScript و PHP؟

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





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

المصفوفات ولغتهم الأم - C


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

في C ، يتم كتابة المصفوفات بقوة ولها طول ثابت.

int myArray[10];
int fibonacci[10] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34};

أعلاه زوجان من إعلانات المصفوفة. يمكنهم فقط تخزين الأعداد الصحيحة ، التي لا يتجاوز عددها 10.

عند العمل مع هذه المصفوفات ، يتم استخدام حلقة for. يتم نسخ هذا النمط ، دون أي حاجة حقيقية ، بالعديد من لغات البرمجة الأخرى:

int i, sum;
for (i = 0; i < 9; i++) {
  sum += fibonacci[i];
}

مثل هذا التصميم لا يبدو جامحًا في جافا سكريبت أو PHP. ولكن هنا يكمن الخطر.

صفائف جافا سكريبت


يمكنك أن تتخيل أن المصفوفات في JavaScript تشبه إلى حد كبير المصفوفات في C. والحقيقة هي أن الإنشاءات التالية تبدو طبيعية تمامًا في JS:

let myArray = [];
let fibonacci = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34];

ومع ذلك ، تعد المصفوفات في JavaScript و C شيئين مختلفين. على سبيل المثال ، من الواضح أن ما يلي غير ممكن في لغة C:

myArray[0] = 5;
myArray[1] = 5.5;
myArray[2] = 'cat';
myArray[3] = [1,2,3];
myArray[4] = (a,b) => {a+b};
myArray[1000] = 'mind blown';
// myArray = [5, 5.5, 'cat', [1,2,3], (a,b) => {a+b}];

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

يمكن تنظيم تعداد الصفيف باستخدام طريقة غير ناجحة مستعارة من C:

let sum = 0;
for (i = 0; i < fibonacci.length; i++) {
  sum += fibonacci[i];
}

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

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

let sum = fibonacci
   .filter(Number.isInteger)
   .reduce(
      (x,y) => {return x+y}, 0
    );

هذا أفضل بكثير من التكرار عبر مصفوفة for.


بعض طرق المصفوفات

، بالإضافة إلى ذلك ، كما ذكرنا من قبل ، لم يتم تحديد طول المصفوفات في JS ، على عكس طول المصفوفات C. يتيح لك ذلك الحصول على تأثيرات مثيرة للاهتمام على المصفوفات التي تؤثر على طولها. لذلك ، باستخدام الطريقة ، يمكنكpopاستخراج العنصر الأخير من الصفيف. pushوتتيح لكالطريقةإضافة عنصر جديد إلى نهاية المصفوفة. unshiftتتيح لكالطريقةإضافة عنصر إلى بداية المصفوفة. والطريقةshiftهي استخراج العنصر الأول من المصفوفة. باستخدام مجموعات مختلفة من هذه الطرق ، يمكنك العمل مع المصفوفات كما هو الحال مع المداخن أو قوائم الانتظار. كل هذا يتوقف على احتياجات المبرمج.

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


تشبه المصفوفات في PHP صفائف JavaScript تقريبًا.

وهي ، مثل صفائف JS ، ذات طول متغير وكتابة ضعيفة. لذلك ، قد يكون من المغري أن تقرر أن المصفوفات في PHP و JS هي نفس الشيء.

$myArray = [];
$fibonacci = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34];
$myArray[0] = 5;
$myArray[1] = 5.5;
$myArray[2] = 'cat';
$myArray[3] = [1,2,3];
$myArray[4] = function($a, $b) { return $a + $b; };

وظائف Lambda في PHP ليست جميلة مثل الوظائف المماثلة في JS (في ES6) ، لكن هذا المثال المكتوب بلغة PHP يكافئ وظيفياً لمثال JS الذي تم اعتباره سابقًا.

يمكن استخدامها ، والوظائف التناظرية الموصوفة أعلاه لإضافة عناصر إلى الصفيف واسترجاعها منها ( array_push، array_pop، array_shift، array_unshift).

ولكن في JavaScript (وكذلك في C) ، لا يمكنك كتابة شيء مشابه لما يلي (بالطبع ، يمكنك كتابة شفرة مماثلة في JavaScript ، لكنها لن تعمل كما هو الحال في PHP):

$myArray['banana'] = 'yellow fruit';
$myArray[5] = 'is alive';
$myArray[0.02] = 'the 2%';

في PHP ، من وجهة نظر فنية ، المصفوفات هي جداول تجزئة أو قواميس. يستخدمون أزواج المفتاح / القيمة. يمكن أن تكون المفاتيح أي قيم بدائية: الأعداد الصحيحة ، أرقام الفاصلة العائمة ، السلاسل. نظرًا لأن مصفوفات php تعتمد على القواميس ، فإن العثور على القيم الرئيسية في هذه المصفوفات فعال للغاية. وهي تعقيد البحث الزمني O(1).

هذا يعني أن صفائف PHP يمكن أن تعمل بنجاح كجداول بحث بسيطة:

$colours = [
  'red' => '#FF0000',
  'green' => '#00FF00',
  'blue' => '#0000FF',
  'orange' => '#FF6600',
];

صفائف PHP تمنح المطور الكثير من المرونة. يمكن فرز هذه المصفوفات حسب المفتاح والقيمة. يمكنك ، على سبيل المثال ، "قلب" مصفوفة مع array_flipتبديل المفاتيح والقيم ، مما يجعل من الممكن تنظيم عملية البحث بكفاءة عالية في مصفوفة البيانات الضرورية.

يستغرق العثور على قيمة محددة في صفيف عادي وقتًا طويلاً O(n)، حيث تحتاج أثناء البحث إلى التحقق من كل قيمة مخزنة في الصفيف. وفي PHP ، من السهل جعل تعقيد الوقت لنفس العملية يصل إلى O(1):

$users = [
  1 => 'Andi',
  2 => 'Benny',
  3 => 'Cara',
  4 => 'Danny',
  5 => 'Emily',
];
$lookupTable = array_flip($users);
return $lookupTable['Benny'];

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

إذا واصلنا المناقشة حول مصفوفات PHP ، فيمكننا القول أن تعدادها منظم ببساطة وأمان. هنا من الممكن تطبيق دورة forتشبه نفس الدورة من C ، ولكن قبل القيام بذلك ، يجب أن تفكر بعناية في سبب القيام بذلك. foreachتتيح لك PHP ، بفضل الحلقات ، حل المشكلات الخاصة بمصفوفات الطول المتغير التي يمكن أن تحتوي على قيم من أنواع مختلفة:

$sum = 0;
foreach ($myArray as $key => $value) {
  $sum += is_numeric($value) ? $value : 0;
}

تتيح الحلقة الوصول إلى كل من المفاتيح والقيم ، مما يسمح للمبرمج بالعمل مع كليهما.

تجدر الإشارة إلى أن صفائف PHP تختلف عن صفائف JS في أنه في PHP يجب عليك استخدام الوظائف الخارجية لهم لإجراء بعض العمليات مع الصفائف:

$sum = 
  array_reduce(
    array_filter($fibonacci, 'is_numeric'),
    function ($x, $y) { return $x + $y; },
    0
  };

إنها عملية ، ولكنها ليست جميلة كما في JavaScript. إذا كنت ترغب في كتابة تعليمات برمجية للعمل مع مصفوفات PHP تشبه التعليمات البرمجية المستخدمة في JavaScript (هناك حجج قوية لصالح هذا النهج) ، فقد تحتاج إلى البحث عن حل متخصص. قل - لفئة Collectionمن إطار Laravel. ومع ذلك ، يتيح لك PHP إنشاء كائنات تشبه قدراتها قدرات المصفوفات (على سبيل المثال ، يمكن معالجتها في حلقات foreach).

إذا كانت PHP هي لغة البرمجة الرئيسية الخاصة بك ، يمكنك أن تعتاد عليها ويمكنك أن تنسى تمامًا القوة التي تكمن في آلياتها الأساسية.

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

ملخص: سؤال وجواب


سؤال : ما هي أوجه التشابه والاختلاف بين المصفوفات في JavaScript و PHP؟

الإجابة : في PHP و JavaScript ، تعد المصفوفات قوائم مكتوبة بشكل ضعيف ذات طول متغير. في JavaScript ، يتم ترتيب مفاتيح عناصر الصفيف بشكل صحيح. في PHP ، يمكن مقارنة المصفوفات بالقوائم التي تدعم الفرز والقواميس التي يسهل فيها البحث عن العناصر حسب المفتاح. يمكن أن تكون مفاتيح صفائف PHP أي قيم للأنواع البدائية ، ويمكنك فرز هذه الصفائف حسب المفاتيح أو القيم.

القراء الأعزاء! ما هي الميزات القياسية التي تعتقد أن صفائف جافا سكريبت تفتقر إليها أكثر من غيرها؟


All Articles