دليل شامل: كيفية عد الكائنات في مصفوفة JavaScript بناءً على شروط محددة
يُعد التعامل مع المصفوفات (Arrays) جزءًا أساسيًا من برمجة JavaScript، وغالبًا ما نحتاج إلى عد العناصر داخلها. بينما توفر خاصية length العدد الإجمالي للعناصر، فإن التحدي الحقيقي يكمن في عد الكائنات التي تستوفي شروطًا معينة فقط. فكيف يمكنك عد الكائنات في مصفوفة بناءً على معايير محددة بكفاءة وفعالية؟
لنفترض أن لديك مصفوفة من الكائنات (objects) مثل هذه:
const storage = [
{ data : '1' , status : '0' },
{ data : '2' , status : '0' },
{ data : '3' , status : '0' },
{ data : '4' , status : '0' },
{ data : '5' , status : '0' },
{ data : '6' , status : '0' },
{ data : '7' , status : '1' },
];
وأن هدفك هو عد الكائنات التي تحتوي على الخاصية status بقيمة '0'. لحسن الحظ، توفر JavaScript عدة طرق لتحقيق ذلك، بدءًا من الحلقات التكرارية التقليدية وصولًا إلى دوال المصفوفات المتقدمة. سنستعرض في هذا المقال أبرز هذه الطرق مع شرح مفصل وأمثلة عملية.
استخدام الحلقات التكرارية للعد الشرطي
تُعد الحلقات التكرارية (loops) من الأدوات الأساسية في أي لغة برمجة، وهي توفر طريقة مباشرة ومفهومة لتصفح عناصر المصفوفة وتطبيق الشروط عليها.
حلقة for التقليدية
تُعد حلقة for الطريقة الأكثر بدائية ووضوحًا للتعامل مع المصفوفات. يمكنك تعريف متغير عداد (counter)، ثم المرور على كل عنصر في المصفوفة، وزيادة العداد فقط إذا استوفى العنصر الشرط المطلوب.
const storage = [
{ data : '1' , status : '0' },
{ data : '2' , status : '0' },
{ data : '3' , status : '0' },
{ data : '4' , status : '0' },
{ data : '5' , status : '0' },
{ data : '6' , status : '0' },
{ data : '7' , status : '1' },
];
let counter = 0 ;
for ( let i = 0 ; i < storage.length; i++) {
if (storage[i].status === '0' ) {
counter++;
}
}
console .log(counter); // الناتج: 6
في هذا المثال، نقوم بتهيئة counter إلى صفر، ثم نكرر عبر المصفوفة storage. لكل كائن، نتحقق مما إذا كانت قيمة status هي '0'. إذا كان الشرط صحيحًا، نزيد العداد.
حلقة for...of المبسّطة
توفر حلقة for...of طريقة أكثر إيجازًا وقراءة للتكرار عبر الكائنات القابلة للتكرار (iterable objects) مثل المصفوفات. إنها تبسط عملية الوصول إلى كل عنصر مباشرة دون الحاجة إلى مؤشر (index).
const storage = [
{ data : '1' , status : '0' },
{ data : '2' , status : '0' },
{ data : '3' , status : '0' },
{ data : '4' , status : '0' },
{ data : '5' , status : '0' },
{ data : '6' , status : '0' },
{ data : '7' , status : '1' },
];
let counter = 0 ;
for ( const obj of storage) {
if (obj.status === '0' ) {
counter++;
}
}
console .log(counter); // الناتج: 6
هذه الطريقة أكثر نظافة وأسهل في الفهم، خاصة عند التعامل مع الكائنات مباشرة داخل المصفوفة.
إنشاء دالة مخصصة للعد
إذا كنت بحاجة إلى عد الكائنات المشروطة في مصفوفات متعددة أو في أجزاء مختلفة من تطبيقك، فإن تغليف منطق العد داخل دالة (function) هو أفضل ممارسة. هذا يعزز قابلية إعادة الاستخدام ويجعل الكود أكثر تنظيمًا.
const storage = [
{ data : '1' , status : '0' },
{ data : '2' , status : '0' },
{ data : '3' , status : '0' },
{ data : '4' , status : '0' },
{ data : '5' , status : '0' },
{ data : '6' , status : '0' },
{ data : '7' , status : '1' },
];
function statusCounter ( inputs ) {
let counter = 0 ;
for ( const input of inputs) {
if (input.status === '0' ) {
counter += 1 ;
}
}
return counter;
}
console .log(statusCounter(storage)); // الناتج: 6
تسمح لك هذه الدالة statusCounter بتمرير أي مصفوفة من الكائنات إليها، وستعيد لك عدد الكائنات التي تستوفي الشرط المحدد.
الاستفادة من دوال المصفوفات المدمجة في JavaScript
توفر JavaScript مجموعة غنية من دوال المصفوفات المدمجة (Array methods) التي تتيح لك معالجة المصفوفات بطرق وظيفية (functional) وفعالة. سنركز هنا على دالتي filter() و reduce() لقدرتهما على تحقيق العد الشرطي بكفاءة.
دالة filter(): تصفية ثم عد
تقوم دالة filter() بإنشاء مصفوفة جديدة تحتوي فقط على العناصر التي تجعل الدالة الاختبارية (callback function) المُمررة إليها تُعيد القيمة true. بعد الحصول على المصفوفة المصفاة، يمكنك ببساطة استخدام خاصية length لعد العناصر.
const storage = [
{ data : '1' , status : '0' },
{ data : '2' , status : '0' },
{ data : '3' , status : '0' },
{ data : '4' , status : '0' },
{ data : '5' , status : '0' },
{ data : '6' , status : '0' },
{ data : '7' , status : '1' },
];
const filteredItems = storage.filter( function ( item ) {
if (item.status === '0' ) { // تم تصحيح الشرط ليتناسب مع نوع البيانات '0'
return true ;
} else {
return false ;
}
});
/*
filteredItems ستكون:
[
{ data: '1', status: '0' },
{ data: '2', status: '0' },
{ data: '3', status: '0' },
{ data: '4', status: '0' },
{ data: '5', status: '0' },
{ data: '6', status: '0' }
]
*/
console .log(filteredItems.length); // الناتج: 6
يمكن تبسيط هذا الكود بشكل كبير باستخدام صيغة ES6 لدوال الأسهم (arrow functions) وسلسلة الدوال (chaining methods):
const storage = [
{ data : '1' , status : '0' },
{ data : '2' , status : '0' },
{ data : '3' , status : '0' },
{ data : '4' , status : '0' },
{ data : '5' , status : '0' },
{ data : '6' , status : '0' },
{ data : '7' , status : '1' },
];
const count = storage.filter( item => item.status === '0' ).length; // الناتج: 6
console .log(count);
هذه الطريقة أنيقة ومقروءة للغاية، حيث تقوم بتصفية المصفوفة ثم الحصول على طول المصفوفة الناتجة في سطر واحد.
دالة reduce(): تحويل المصفوفة إلى قيمة واحدة
تُعد دالة reduce() أداة متعددة الاستخدامات، أشبه بسكين الجيش السويسري للمصفوفات. تسمح لك بتحويل المصفوفة إلى قيمة واحدة (يمكن أن تكون رقمًا، كائنًا، مصفوفة جديدة، إلخ) عن طريق تطبيق دالة callback على كل عنصر وتجميع النتائج.
في سياق العد الشرطي، يمكننا استخدام reduce() لإنشاء عداد يقوم بزيادة قيمته كلما استوفى العنصر الشرط.
const storage = [
{ data : '1' , status : '0' },
{ data : '2' , status : '0' },
{ data : '3' , status : '0' },
{ data : '4' , status : '0' },
{ data : '5' , status : '0' },
{ data : '6' , status : '0' },
{ data : '7' , status : '1' },
];
const count = storage.reduce( ( counter, obj ) => {
if (obj.status === '0' ) {
counter += 1 ;
}
return counter;
}, 0 ); // القيمة الأولية للعداد هي 0
console .log(count); // الناتج: 6
هنا، counter هو المجمّع (accumulator) الذي يبدأ بقيمة 0. في كل تكرار، نتحقق من obj.status، وإذا كان '0'، نزيد العداد. في النهاية، تُعيد الدالة القيمة النهائية للعداد.
يمكن تبسيط هذا الكود أكثر باستخدام صيغة ES6 وعامل التشغيل الثلاثي (ternary operator):
const storage = [
{ data : '1' , status : '0' },
{ data : '2' , status : '0' },
{ data : '3' , status : '0' },
{ data : '4' , status : '0' },
{ data : '5' , status : '0' },
{ data : '6' , status : '0' },
{ data : '7' , status : '1' },
];
const count = storage.reduce(
( counter, obj ) => obj.status === '0' ? counter += 1 : counter,
0
);
console .log(count); // الناتج: 6
ولمزيد من النظافة وقابلية القراءة، يمكن استخدام تفكيك الكائنات (object destructuring) للوصول مباشرة إلى الخاصية status:
const storage = [
{ data : '1' , status : '0' },
{ data : '2' , status : '0' },
{ data : '3' , status : '0' },
{ data : '4' , status : '0' },
{ data : '5' , status : '0' },
{ data : '6' , status : '0' },
{ data : '7' , status : '1' },
];
const count = storage.reduce(
( counter, { status } ) => status === '0' ? counter += 1 : counter,
0
);
console .log(count); // الناتج: 6
الخلاصة التقنية
لقد استعرضنا في هذا المقال عدة طرق فعالة لعد الكائنات في مصفوفات JavaScript بناءً على شروط محددة. كل طريقة لها مزاياها واستخداماتها المثلى:
- تُعد الحلقات التكرارية (
forوfor...of) خيارًا ممتازًا للمبتدئين أو عند الحاجة إلى تحكم دقيق في عملية التكرار، كما أنها غالبًا ما تكون الأسرع أداءً في بعض السيناريوهات البسيطة. - توفر الدوال المخصصة قابلية إعادة استخدام ممتازة وتساعد في تنظيم الكود.
- تُعد دالة
filter()الخيار الأمثل عندما يكون هدفك ليس فقط العد، بل أيضًا الحصول على مصفوفة جديدة تحتوي على العناصر التي تستوفي الشرط. ثم يمكنك ببساطة استخدام.lengthللحصول على العدد. - تُعد دالة
reduce()الأداة الأكثر مرونة وقوة، ومناسبة عندما تحتاج إلى تحويل المصفوفة إلى قيمة واحدة معقدة، بما في ذلك العد الشرطي. إنها توفر حلولًا أنيقة وموجزة، خاصة مع استخدام دوال الأسهم وتفكيك الكائنات.
اختيار الطريقة الأنسب يعتمد على تفضيلاتك الشخصية، متطلبات الأداء، ومدى تعقيد الشرط، وقابلية القراءة التي تسعى إليها في مشروعك. المهم هو أن تكون واثقًا من قدرتك على التعامل مع المصفوفات بفعالية في أي سيناريو برمجي.