javascript - لكل من خلال مجموعة في جافا سكريبت؟




arrays loops foreach iteration (24)

كيف يمكنني تكرار جميع الإدخالات في صفيف باستخدام JavaScript؟

اعتقدت انه شيء من هذا القبيل:

forEach(instance in theArray)

أين هو theArray ، ولكن يبدو أن هذا غير صحيح.


Answers

عن طريق حلقات مع ES6 destructuring و مشغل انتشار

لقد أثبتت عملية التدمير واستخدام مشغِّل النشر فائدة كبيرة للقادمين الجدد إلى ES6 على أنها أكثر قابلية للقراءة / الجمالية ، على الرغم من أن بعض قدامى المحاربين في جافا سكريبت قد يعتبرونها فوضويًا أو صغارًا أو قد يجدها البعض الآخر مفيدة.

سوف تستخدم الأمثلة التالية for...ofالعبارة .forEachوالطريقة.

يمكن استخدام الأمثلة 6 و 7 و 8 مع أي حلقات وظيفية مثل .map، .filter، .reduce، .sort، .every، .some، لمزيد من المعلومات حول هذه الطرق تحقق من كائن الصفيف .

مثال 1:for...of حلقة عادية - لا توجد حيل هنا.

let arrSimple = ['a', 'b', 'c'];

for (let letter of arrSimple) {
  console.log(letter);
}

مثال 2: تقسيم الكلمات إلى أحرف

let arrFruits = ['apple', 'orange', 'banana'];

for (let [firstLetter, ...restOfTheWord] of arrFruits) {
  // Create a shallow copy using the spread operator
  let [lastLetter] = [...restOfTheWord].reverse();
  console.log(firstLetter, lastLetter, restOfTheWord);

}

المثال 3: التكرار مع keyوvalue

// let arrSimple = ['a', 'b', 'c'];

// Instead of keeping an index in `i` as per example `for(let i = 0 ; i<arrSimple.length;i++)`
// this example will use a multi-dimensional array of the following format type: 
// `arrWithIndex: [number, string][]`

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Same thing can be achieved using `.map` method
// let arrWithIndex = arrSimple.map((i, idx) => [idx, i]);

// Same thing can be achieved using `Object.entries`
// NOTE: `Object.entries` method doesn't work on internet explorer unless it's polyfilled
// let arrWithIndex = Object.entries(arrSimple);

for (let [key, value] of arrWithIndex) {
  console.log(key, value);
}

مثال 4: الحصول على خصائص الكائن مضمنة

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];

for (let { name, age: aliasForAge } of arrWithObjects) {
  console.log(name, aliasForAge);
}

مثال 5: احصل على خصائص الكائن العميق لما تحتاجه

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

for (let { name, tags: [firstItemFromTags, ...restOfTags] } of arrWithObjectsWithArr) {
  console.log(name, firstItemFromTags, restOfTags);
}

المثال 6: هل المثال 3 مستخدم مع.forEach

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Not to be confused here, `forEachIndex` is the real index
// `mappedIndex` was created by "another user", so you can't really trust it

arrWithIndex.forEach(([mappedIndex, item], forEachIndex) => {
  console.log(forEachIndex, mappedIndex, item);
});

المثال 7: هل المثال 4 مستخدم مع.forEach

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];
// NOTE: Destructuring objects while using shorthand functions 
// are required to be surrounded by parenthesis
arrWithObjects.forEach( ({ name, age: aliasForAge }) => {
  console.log(name, aliasForAge)
});

مثال 8: هل المثال 5 مستخدم مع.forEach

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

arrWithObjectsWithArr.forEach(({
  name,
  tags: [firstItemFromTags, ...restOfTags]
}) => {
  console.log(name, firstItemFromTags, restOfTags);
});


لا يعمل بناء الجملة لامدا عادة في IE 10 أو أقل.

أنا عادة ما تستخدم

[].forEach.call(arrayName,function(value,index){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});


If you are a jQuery Fan and already have a jQuery file running, you should reverse the positions of the index and value parameters

$("#ul>li").each(function(**index,value**){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});

for(let i=0;i<theArray.length;i++){
  console.log(i); //i will have the value of each index
}

إذا كنت ترغب في استخدامها forEach()، سيبدو -

theArray.forEach ( element => { console.log(element); });

إذا كنت ترغب في استخدامها for()، سيبدو -

for(let idx = 0; idx < theArray.length; idx++){ let element = theArray[idx]; console.log(element); }


لا توجد أي for eachحلقة في JavaScript الأصلي . يمكنك استخدام المكتبات للحصول على هذه الوظيفة (أوصي بـ Underscore.js ) ، استخدم forحلقة بسيطة في حلقة.

for (var instance in objects) {
   ...
}

ومع ذلك ، لاحظ أنه قد تكون هناك أسباب لاستخدام forحلقة أبسط من ذلك (انظر السؤال حول لماذا يستخدم "for… in" مع تكرار الصفات مثل هذه الفكرة السيئة؟ )

var instance;
for (var i=0; i < objects.length; i++) {
    var instance = objects[i];
    ...
}

ECMAScript5 (الإصدار الموجود على Javascript) للعمل مع صفائف.

forEach - يتكرر من خلال كل عنصر في الصفيف وتفعل كل ما تحتاجه مع كل عنصر.

['C', 'D', 'E'].forEach(function(element, index) {
  console.log(element + " is the #" + (index+1) + " in musical scale");
});

// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale

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

map - يقوم بإنشاء مصفوفة جديدة مع نتيجة وظيفة رد الاتصال. هذه الطريقة جيدة لاستخدامها عندما تحتاج إلى تنسيق عناصر المصفوفة الخاصة بك.

// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
  return elem.toUpperCase();
});

// Output: ['BOB', 'JOE', 'JEN']

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

[1,2,3,4].reduce(function(previous, current) {
  return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10

every - إرجاع true أو false إذا اجتازت جميع العناصر في الصفيف الاختبار في وظيفة رد الاتصال.

// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];  
ages.every(function(elem) {  
  return elem >= 18;
});

// Output: false

مرشح - تشبه إلى حد كبير كل ما عدا ذلك المرشح بإرجاع مصفوفة مع العناصر التي ترجع صحتها إلى وظيفة معينة.

// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
  return (elem % 2 == 0)
});

// Output: [2,4,6]

اتمني ان يكون ذلك مفيدا.


إذا كنت تستخدم مكتبة jQuery ، فيمكنك استخدام jQuery.each :

$.each(yourArray, function(index, value) {
  // do your stuff here
});

تصحيح :

وفقًا للسؤال ، يريد المستخدم رمزًا في javascript بدلاً من jquery حتى يكون التعديل

var length = yourArray.length;   
for (var i = 0; i < length; i++) {
  // Do something with yourArray[i].
}

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

  • forEach
  • خريطة
  • منقي
  • الرمز البريدي
  • خفض
  • كل
  • بعض

الطريقة القياسية لتكرار صفيف في JavaScript هو الفانيلا من for :

var length = arr.length,
    element = null;
for (var i = 0; i < length; i++) {
  element = arr[i];
  // Do something with element
}

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

في ECMAScript 5 سيكون هناك أسلوب forEach في النموذج الأولي للمصفوفة ، ولكنه غير مدعوم في المتصفحات القديمة. حتى تكون قادرًا على استخدامه باستمرار ، يجب أن يكون لديك بيئة تدعمه (على سبيل المثال ، Node.js لجافا سكريبت من جانب الخادم) ، أو استخدام "Polyfill". ومع ذلك ، فإن Polyfill لهذه الوظيفة بسيط ، ولأنه يسهل قراءة الكود ، فإنه يعتبر تهيئته جيدًا لتضمينه.


تطبيق forEach ( انظر في jsFiddle ):

function forEach(list,callback) {
  var length = list.length;
  for (var n = 0; n < length; n++) {
    callback.call(list[n]);
  }
}

var myArray = ['hello','world'];

forEach(
  myArray,
  function(){
    alert(this); // do something
  }
);

طريقة jQuery باستخدام $.map:

var data = [1, 2, 3, 4, 5, 6, 7];

var newData = $.map(data, function(element) {
    if (element % 2 == 0) {
        return element;
    }
});

// newData = [2, 4, 6];

عروة للخلف

أعتقد أن العكس للحلقة يستحق الذكر هنا:

for (var i = array.length; i--; ) {
     // process array[i]
}

مزايا:

  • لا تحتاج إلى إعلان متغير len مؤقت ، أو مقارنة ضد array.length في كل تكرار ، قد يكون أي منهما array.length .
  • إزالة الأشقاء من DOM بترتيب عكسي عادة ما تكون أكثر كفاءة . (يحتاج المتصفح إلى تقليل نقل العناصر في صفائفه الداخلية.)
  • إذا قمت بتعديل المصفوفة أثناء التكرار ، أو عند الفهرس i (على سبيل المثال قمت بإزالة عنصر أو إدراجه في array[i] ) ، فستتخطى حلقة أمامية العنصر الذي تحول إلى اليسار في الموضع i ، أو تعيد معالجة i. البند عشر الذي تم نقله الحق. في حلقة تقليدية ، يمكنك تحديث i للإشارة إلى العنصر التالي الذي يحتاج إلى معالجة - 1 ، ولكن ببساطة عكس اتجاه التكرار هو غالباً حل أبسط وأنيق .
  • وبالمثل ، عند تعديل عناصر DOM المتداخلة أو إزالتها ، يمكن للمعالجة في الاتجاه المعاكس التحايل على الأخطاء . على سبيل المثال ، فكر في تعديل innerHTML لعقدة رئيسية قبل التعامل مع الأطفال. في الوقت الذي يتم فيه الوصول إلى العقدة الفرعية ، سيتم فصله عن DOM ، بعد أن تم استبداله بطفل تم إنشاؤه حديثًا عندما تم كتابة لغة HTML الداخلية.
  • من الأقصر الكتابة والقراءة أكثر من بعض الخيارات الأخرى المتاحة. على الرغم من أنه يخسر ل forEach() و ES6 ل for ... of .

سلبيات:

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

هل يجب علي دائمًا استخدامها؟

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

على الرغم من أن مكاسب الأداء عادةً ما تكون غير ذات أهمية ، إلا أنها نوع من الصراخ:

"فقط افعل ذلك لكل عنصر في القائمة ، لا يهمني الأمر!"

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

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

من الأفضل استخدام forEach ()

بوجه عام ، بالنسبة إلى الشفرة ذات المستوى الأعلى حيث تُعد درجة الوضوح والسلامة من المخاوف الأكبر ، فإنني Array::forEach باستخدام Array::forEach الافتراضي:

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

بعد ذلك ، عندما ترى عكس الحل في الشفرة ، فهذا تلميح إلى أنه يتم عكسه لسبب وجيه (ربما أحد الأسباب الموضحة أعلاه). ورؤية التتابع التقليدي للحلقة قد يشير إلى أن التحول قد يحدث.

(إذا لم تكن مناقشة النوايا منطقية بالنسبة لك ، فقد تستفيد أنت ورمزك من مشاهدة محاضرة كروكفورد حول أسلوب البرمجة ودماغك .)

كيف يعمل؟

for (var i = 0; i < array.length; i++) { ... }   // Forwards

for (var i = array.length; i--; )    { ... }   // Reverse

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

  • كيف يمكن أن تبدأ في array.length دون انفجار؟

    نظرًا لأن i-- يعمل قبل كل عملية تكرار ، ففي أول عملية تكرار ، سنتمكن بالفعل من الوصول إلى العنصر في array.length - 1 الذي يتجنب أي مشكلات تتعلق array.length - 1 خارج النطاق undefined .

  • لماذا لا يتوقف عن التكرار قبل الفهرس 0؟

    ستتوقف الحلقة عن التكرار عند تقييم الحالة i-- إلى قيمة falsey (عندما تعطي 0).

    الخدعة هي أنه على عكس - --i ، يتتبع مشغل i trailing i ولكنه يعطي القيمة قبل الانخفاض. يمكن أن توضح وحدة التحكم الخاصة بك هذا:

    > var i = 5; [i, i--, i];

    [5, 5, 4]

    إذن في التكرار النهائي ، كنت في السابق 1 والتعبير i-- يغيره إلى 0 ولكنه في الواقع ينتج 1 (صحيح) ، وهكذا تمر الحالة. في التكرار التالي i - يتغير i إلى -1 ولكن ينتج 0 (falsey) ، مما يؤدي إلى تنفيذ التنفيذ على الفور من أسفل الحلقة.

    في العقود التقليدية للحلقة ، i++ و ++i قابلة للتبادل (كما يشير دوغلاس كروكفورد). ولكن في الاتجاه المعاكس للحلقة ، لأن تناقصنا هو أيضًا تعبير الحالة الخاص بنا ، يجب علينا الالتزام بـ i-- إذا أردنا معالجة العنصر في index 0.

توافه

يحب بعض الأشخاص رسم سهم صغير في الاتجاه المعاكس للحلقة ، وينتهي بغمزة:

for (var i = array.length; i --> 0 ;) {

تذهب الاعتمادات إلى WYL لتعرض لي فوائد وأهوال العكس للحلقة.


أود أيضًا أن أضيف هذا كتكوين لحلقة عكسية وإجابة أعلاه لشخص يرغب في هذا النحو أيضًا.

var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
    console.log(item);
}

الايجابيات:

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

سلبيات:

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


إذا كنت تريد التكرار عبر صفيف ، استخدم الحلقة القياسية الثلاثية الأجزاء.

for (var i = 0; i < myArray.length; i++) {
    var arrayItem = myArray[i];
}

يمكنك الحصول على بعض تحسينات الأداء من خلال التخزين المؤقت myArray.length أو التكرار فوقه إلى الخلف.


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

ل- انها الاكثر شيوعا. كتلة كاملة من التعليمات البرمجية لحلقات

var languages = ["JAVA", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
    text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

بينما - حلقة في حين أن الشرط من خلال. يبدو أن الحلقة الأسرع

var text = "";
var i = 0;
while (i < 10) {
    text +=  i + ") something<br>";
    i++;
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

القيام / أثناء - أيضًا التكرار من خلال كتلة من التعليمات البرمجية أثناء تحقق الشرط ، سيتم تشغيله مرة واحدة على الأقل

var text = ""
var i = 0;
do {
    text += i + ") something <br>";
    i++;
}
while (i < 10);
document.getElementById("example").innerHTML = text;
<p id="example"></p>

الحلقات الوظيفية - forEach، map، filterأيضًا reduce(يتم تكرارها من خلال الدالة ، ولكن يتم استخدامها إذا كنت بحاجة إلى إجراء شيء ما مع الصفيف ، إلخ.

// For example, in this case we loop through the number and double them up using the map function
var numbers = [65, 44, 12, 4];
document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
<p id="example"></p>

لمزيد من المعلومات والأمثلة حول البرمجة الوظيفية على المصفوفات ، انظر إلى مشاركة المدونة البرمجة الوظيفية في JavaScript: خريطة وتصفية وتقليل .


ربما for(i = 0; i < array.length; i++)لا يكون الحل هو الاختيار الأفضل. لماذا ا؟ إذا كان لديك هذا:

var array = new Array();
array[1] = "Hello";
array[7] = "World";
array[11] = "!";

إن أسلوب دعوة من array[0]ل array[2]. أولاً ، سيحدد هذا أولاً المتغيرات التي لا تمتلكها حتى ، وثانياً لن يكون لديك المتغيرات في الصفيف ، والثالث هذا سيجعل رمز الشفرة أكبر. انظر هنا ، هذا ما أستخدمه:

for(var i in array){
    var el = array[i];
    //If you want 'i' to be INT just put parseInt(i)
    //Do something with el
}

وإذا كنت تريد أن تكون وظيفة ، فيمكنك القيام بذلك:

function foreach(array, call){
    for(var i in array){
        call(array[i]);
    }
}

إذا كنت تريد أن تنكسر ، فهناك منطق أكثر بقليل:

function foreach(array, call){
    for(var i in array){
        if(call(array[i]) == false){
            break;
        }
    }
}

مثال:

foreach(array, function(el){
    if(el != "!"){
        console.log(el);
    } else {
        console.log(el+"!!");
    }
});

يعود:

//Hello
//World
//!!!

هناك ثلاثة تطبيقات foreachفي jQuery النحو التالي.

var a = [3,2];

$(a).each(function(){console.log(this.valueOf())}); //Method 1
$.each(a, function(){console.log(this.valueOf())}); //Method 2
$.each($(a), function(){console.log(this.valueOf())}); //Method 3

يمكنك الاتصال forEach مثل هذا:

var a = ["car", "bus", "truck"]
a.forEach(function(item, index) {
    console.log("Index" + index);
    console.log("Element" + item);
})

عنصر سيكون له قيمة كل فهرس من 0 إلى طول الصفيف.

انتاج:

let Array = [1,3,2];

theArray.forEach((element)=>{ 
  // use the element of the array
  console.log(element) 
}

كسبلايناتيون:

forEach في فئة النموذج الأولي. يمكنك أيضًا الاتصال بهذا الاسم asArray.prototype.forEach (...)؛

prototype: https://hackernoon.com/prototypes-in-javascript-5bba2990e04b

يمكنك أيضًا التبديل عبر مجموعة مثل هذه:

1    
3    
2

اعتبارا من ES6:

list = [0, 1, 2, 3]
for (let obj of list) {
    console.log(obj)
}

حيث ofيتجنب الشذوذ المرتبط به inويجعله يعمل مثل forحلقة أي لغة أخرى ، letويربط iداخل الحلقة بدلاً من داخل الوظيفة.

{}يمكن حذف الأقواس ( ) عند وجود أمر واحد فقط (على سبيل المثال في المثال أعلاه).


تستخدم بعض لغات C -style foreach خلال التعدادات. في جافا سكريبت يتم ذلك باستخدام بنية الحلقة في :

var index,
    value;
for (index in obj) {
    value = obj[index];
}

هناك الصيد. for..in سوف حلقة من خلال كل من أعضاء الكائن لا تعد ولا تحصى ، وأعضاء على النموذج الأولي لها. لتجنب قراءة القيم الموروثة من خلال النموذج الأولي للكائن ، ما عليك سوى التحقق مما إذا كان الموقع ينتمي إلى الكائن:

for (i in obj) {
    if (obj.hasOwnProperty(i)) {
        //do stuff
    }
}

بالإضافة إلى ذلك ، قام ECMAScript 5 بإضافة طريقة forEach إلى Array.prototype والتي يمكن استخدامها في التعداد عبر مصفوفة باستخدام calback (يوجد polyfill في المستندات حتى تتمكن من الاستمرار في استخدامه للمتصفحات القديمة):

arr.forEach(function (val, index, theArray) {
    //do stuff
});

من المهم ملاحظة أن Array.prototype.forEach لا تنكسر عند إرجاع الاستدعاء false . jQuery و Underscore.js الخاصة each لتوفير حلقات يمكن أن تكون قصيرة الدارة.


إذا كنت لا تمانع في إفراغ الصفيف:

var x;

while(x = y.pop()){ 

    alert(x); //do something 

}

xسيحتوي على القيمة الأخيرة yوسيتم إزالته من المصفوفة. يمكنك أيضًا استخدام shift()الذي سيعطي العنصر الأول وإزالته منه y.


يعد هذا تكرارًا لقائمة NON-sparse حيث يبدأ الفهرس عند 0 ، وهو السيناريو النموذجي عند التعامل مع document.getElementsByTagName أو document.querySelectorAll)

function each( fn, data ) {

    if(typeof fn == 'string')
        eval('fn = function(data, i){' + fn + '}');

    for(var i=0, L=this.length; i < L; i++) 
        fn.call( this[i], data, i );   

    return this;
}

Array.prototype.each = each;  

أمثلة على الاستخدام:

مثال 1

var arr = [];
[1, 2, 3].each( function(a){ a.push( this * this}, arr);
arr = [1, 4, 9]

المثال رقم 2

each.call(document.getElementsByTagName('p'), "this.className = data;",'blue');

يحصل كل علامة p class="blue"

المثال رقم 3

each.call(document.getElementsByTagName('p'), 
    "if( i % 2 == 0) this.className = data;",
    'red'
);

كل علامة p أخرى يحصل class="red">

مثال # 4

each.call(document.querySelectorAll('p.blue'), 
    function(newClass, i) {
        if( i < 20 )
            this.className = newClass;
    }, 'green'
);

وأخيرًا ، يتم تغيير أول 20 علامة زرقاء إلى اللون الأخضر

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


أعرف أن هذه رسالة قديمة ، وهناك العديد من الإجابات الرائعة بالفعل. لمزيد من الاكتمال كنت أحسب في واحدة أخرى باستخدام AngularJS . بالطبع ، هذا ينطبق فقط إذا كنت تستخدم Angular ، من الواضح ، مع ذلك ، أود أن أضعه على أية حال.

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

هناك طرق مختلفة لاستخدام حلقة forEach الزاوية. أبسط وربما الأكثر استخداما

var temp = [1, 2, 3];
angular.forEach(temp, function(item) {
    //item will be each element in the array
    //do something
});

طريقة أخرى مفيدة لنسخ العناصر من صفيف إلى آخر

var temp = [1, 2, 3];
var temp2 = [];
angular.forEach(temp, function(item) {
    this.push(item); //"this" refers to the array passed into the optional third parameter so, in this case, temp2.
}, temp2);

على الرغم من أنك لست بحاجة إلى القيام بذلك ، يمكنك ببساطة القيام بما يلي ، وهو ما يعادل المثال السابق:

angular.forEach(temp, function(item) {
    temp2.push(item);
});

الآن هناك إيجابيات وسلبيات استخدام هذه angular.forEachالوظيفة على عكس forحلقة النكهة المبنية بالفانيليا .

الايجابيات

  • سهولة القراءة
  • سهولة الكتابة
  • إذا كان متاحًا ، angular.forEachفستستخدم حلقة forEach ES5. الآن ، سأحصل على الكفاءة في القسم السلبيات ، لأن حلقات forEach أبطأ بكثير من الحلقات. أذكر هذا كمحترف لأنه من الجيد أن تكون متسقة وموحدة.

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

angular.forEach(obj1.results, function(result1) {
    angular.forEach(obj2.results, function(result2) {
        if (result1.Value === result2.Value) {
            //do something
        }
    });
});

//exact same with a for loop
for (var i = 0; i < obj1.results.length; i++) {
    for (var j = 0; j < obj2.results.length; j++) {
        if (obj1.results[i].Value === obj2.results[j].Value) {
            //do something
        }
    }
}

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

سلبيات

  • نجاعة. angular.forEach، والأصلي forEach، لهذه المسألة ، كلاهما أبطأ بكثير من forالحلقة الطبيعية .... حوالي 90 ٪ أبطأ . لذا بالنسبة لمجموعات البيانات الكبيرة ، من الأفضل الالتزام forبالحلقة المحلية .
  • لا يوجد كسر ، أو الاستمرار ، أو العودة الدعم. continueهو في الواقع مدعوم من قبل " accident " ، لتستمر في angular.forEachوضع بسيطة لك return;بيان في وظيفة مثل angular.forEach(array, function(item) { if (someConditionIsTrue) return; });الذي سيؤدي إلى استمراره خارج وظيفة ذلك التكرار. ويرجع ذلك أيضًا إلى حقيقة أن الشركة الأم forEachلا تدعم الاختراق أو تستمر أيضًا.

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


الحل السهل الآن هو استخدام مكتبة underscore.js . إنه يوفر العديد من الأدوات المفيدة ، مثل eachسيقوم تلقائيًا بتفويض المهمة إلى السكان الأصليين forEachإذا كانت متوفرة.

مثال CodePen عن كيفية عمله هو:

var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});

أنظر أيضا

  • Array::forEach .
  • في for_each...in (MDN) ، يتم شرح ذلك بأنه for each (variable in object)تم إيقافه كجزء من معيار ECMA-357 ( EAX ).
  • for...of (MDN) يصف الطريقة التالية لتكرار استخدامه for (variable of object)كجزء من اقتراح Harmony (ECMAScript 6).

يتمثل الأسلوب الأمثل في تخزين طول صفيف البيانات واستخدام نمط var الفردي الذي يقوم بتهيئة جميع المتغيرات بكلمة var مفردة.

var i, max, myStringArray = ["Hello","World"];
for (i = 0, max = myStringArray.length; i < max; i++) {
    alert(myStringArray[i]);
   //Do something
}

إذا كان ترتيب التكرار لا يهم من المحاولة العكسية ، فهو أسرع لأنه يقلل من اختبار الحالة العلوية ويكون الإنقاص في عبارة واحدة:

var i,myStringArray = ["item1","item2"];
for (i =  myStringArray.length; i--) {
    alert(myStringArray[i]);
}

أو أفضل وأنظف للاستخدام أثناء التكرار:

var myStringArray = ["item1","item2"],i = myStringArray.length;
while(i--) {
   // do something with fruits[i]
}




javascript arrays loops foreach iteration