الاستخدام الفعال لطرق الصفيف في جافا سكريبت

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



استبدال indexOf () بـ ()


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

على MDN ، يمكنك معرفة أن طريقة indexOf() بإرجاع الفهرس الأول الذي يمكن من خلاله العثور على عنصر معين في الصفيف. هذا يعني أنه إذا كنا نخطط لاستخدام هذا الفهرس في البرنامج ، فإن طريقة indexof() رائعة للعثور على العناصر في المصفوفات.

ولكن ماذا لو كنا بحاجة فقط لمعرفة ما إذا كان هناك عنصر معين في الصفيف أم لا؟ أي أننا لسنا مهتمين بفهرس هذا العنصر ، إذا كان في الصفيف ، ولكن في حقيقة وجوده أو غيابه. مع هذا النهج ، نحن مرتاحون تمامًا لأمر يعيد true أو false . في مثل هذه الحالات ، أوصي بعدم استخدام طريقة indexOf() ، ولكن طريقة indexOf() التي تُرجع قيمة منطقية. فكر في مثال:

 'use strict'; const characters = [ 'ironman', 'black_widow', 'hulk', 'captain_america', 'hulk', 'thor', ]; console.log(characters.indexOf('hulk')); // 2 console.log(characters.indexOf('batman')); // -1 console.log(characters.includes('hulk')); // true console.log(characters.includes('batman')); // false 

استخدام طريقة find () بدلا من طريقة filter ()


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

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

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

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

 'use strict'; const characters = [ { id: 1, name: 'ironman' }, { id: 2, name: 'black_widow' }, { id: 3, name: 'captain_america' }, { id: 4, name: 'captain_america' }, ]; function getCharacter(name) { return character => character.name === name; } console.log(characters.filter(getCharacter('captain_america'))); // [ //   { id: 3, name: 'captain_america' }, //   { id: 4, name: 'captain_america' }, // ] console.log(characters.find(getCharacter('captain_america'))); // { id: 3, name: 'captain_america' } 

استبدال طريقة find () بطريقة some ()


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

في الحالة المذكورة أعلاه ، رأينا أن أسلوب find() ، كوسيطة ، يأخذ رد اتصال ويعيد عنصر صفيف. هل يمكن استدعاء الأسلوب find() الحل الأكثر نجاحًا إذا احتجنا إلى معرفة ما إذا كان الصفيف يحتوي على قيمة معينة أم لا؟ ربما لا ، لأن هذه الطريقة تُرجع قيمة عنصر الصفيف ، وليس قيمة منطقية.

في مثل هذه الحالة ، أوصي باستخدام طريقة some() ، التي تُرجع قيمة منطقية.

 'use strict'; const characters = [ { id: 1, name: 'ironman', env: 'marvel' }, { id: 2, name: 'black_widow', env: 'marvel' }, { id: 3, name: 'wonder_woman', env: 'dc_comics' }, ]; function hasCharacterFrom(env) { return character => character.env === env; } console.log(characters.find(hasCharacterFrom('marvel'))); // { id: 1, name: 'ironman', env: 'marvel' } console.log(characters.some(hasCharacterFrom('marvel'))); // true 

استخدام طريقة تقليل () بدلاً من تركيبة من طرق التصفية () و map ()


وتجدر الإشارة إلى أنه لا يمكن تصنيف طريقة reduce() على أنها سهلة الفهم. ومع ذلك ، إذا تم القيام بما يمكن القيام به به في خطوتين ، باستخدام طرق filter() و map() مجتمعة في سلسلة ، فيبدو أن هناك خطأ في هذا النهج.

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

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

في حالتنا ، نظرًا لأننا نتحدث عن استخدام طريقة map() ، فإنني أنصح باستخدام طريقة reduce() مع صفيف كمراكم. في المثال التالي ، نقوم بتصفية عناصر المصفوفة التي هي كائنات حسب قيمة حقل env .

 'use strict'; const characters = [ { name: 'ironman', env: 'marvel' }, { name: 'black_widow', env: 'marvel' }, { name: 'wonder_woman', env: 'dc_comics' }, ]; console.log( characters   .filter(character => character.env === 'marvel')   .map(character => Object.assign({}, character, { alsoSeenIn: ['Avengers'] })) ); // [ //   { name: 'ironman', env: 'marvel', alsoSeenIn: ['Avengers'] }, //   { name: 'black_widow', env: 'marvel', alsoSeenIn: ['Avengers'] } // ] console.log( characters   .reduce((acc, character) => {     return character.env === 'marvel'       ? acc.concat(Object.assign({}, character, { alsoSeenIn: ['Avengers'] }))       : acc;   }, []) ) // [ //   { name: 'ironman', env: 'marvel', alsoSeenIn: ['Avengers'] }, //   { name: 'black_widow', env: 'marvel', alsoSeenIn: ['Avengers'] } // ] 

الملخص


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

أعزائي القراء! هل سبق لك أن واجهت أمثلة على سوء تخصيص آليات JavaScript؟

Source: https://habr.com/ru/post/ar422091/


All Articles