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



Answers

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

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

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

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

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

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

Question

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

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

forEach(instance in theArray)

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




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

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

هناك طرق مختلفة لاستخدام حلقة forEach الزاوية. The simplest and probably most used is

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

Another way that is useful for copying items from one array to another is

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);

Though, you don't have to do that, you can simply do the following and it's equivalent to the previous example:

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

Now there are pros and cons of using the angular.forEach function as opposed to the built in vanilla-flavored for loop.

Pros

  • Easy readability
  • Easy writability
  • If available, angular.forEach will use the ES5 forEach loop. Now, I will get to efficientcy in the cons section, as the forEach loops are much slower than the for loops. I mention this as a pro because it's nice to be consistent and standardized.

Consider the following 2 nested loops, which do exactly the same thing. Let's say that we have 2 arrays of objects and each object contains an array of results, each of which has a Value property that's a string (or whatever). And let's say we need to iterate over each of the results and if they're equal then perform some action:

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
        }
    }
}

Granted this is a very simple hypothetical example, but I've written triple embedded for loops using the second approach and it was very hard to read, and write for that matter.

Cons

  • Efficiency. angular.forEach , and the native forEach , for that matter, are both so much slower than the normal for loop....about 90% slower . So for large data sets, best to stick to the native for loop.
  • No break, continue, or return support. continue is actually supported by " accident ", to continue in an angular.forEach you simple put a return; statement in the function like angular.forEach(array, function(item) { if (someConditionIsTrue) return; }); which will cause it to continue out of the function for that iteration. This is also due to the fact that the native forEach does not support break or continue either.

I'm sure there's various other pros and cons as well, and please feel free to add any that you see fit. I feel that, bottom line, if you need efficiency, stick with just the native for loop for your looping needs. But, if your datasets are smaller and a some efficiency is okay to give up in exchange for readability and writability, then by all means throw an angular.forEach in that bad boy.




An easy solution now would be to use the underscore.js library . It's providing many useful tools, such as each and will automatically delegate the job to the native forEach if available.

A CodePen example of how it works is:

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

أنظر أيضا

  • Array::forEach .
  • In for_each...in (MDN) it is explained that for each (variable in object) is deprecated as the part of ECMA-357 ( EAX ) standard.
  • for...of (MDN) describes the next way of iterating using for (variable of object) as the part of the Harmony (ECMAScript 6) proposal.



There are a few ways to loop through an array in JavaScript, as below:

for - it's the most common one. Full block of code for looping

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>

while - loop while a condition is through. It seems to be the fastest loop

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

do/while - also loop through a block of code while the condition is true, will run at least one time

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

Functional loops - forEach , map , filter , also reduce (they loop through the function, but used if you need to do something with your array, etc.

// 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>

For more information and examples about functional programming on arrays, look at the blog post Functional programming in JavaScript: map, filter and reduce .




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

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

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




عروة للخلف

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

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 الذي يتجنب أي مشكلات تتعلق بالعناصر 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 لتعرض لي فوائد وأهوال العكس للحلقة.




Probably the for(i = 0; i < array.length; i++) loop is not the best choice. لماذا ا؟ If you have this:

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

The method will call from array[0] to array[2] . First, this will first reference variables you don't even have, second you would not have the variables in the array, and third this will make the code bolder. Look here, it's what I use:

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

And if you want it to be a function, you can do this:

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

If you want to break, a little more logic:

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
//!!!



jQuery way using $.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];



ECMAScript5 (the version on Javascript) to work with Arrays.

forEach - Iterates through every item in the array and do whatever you need with each item.

['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

In case , more interested on operation on array using some inbuilt feature.

map - It creates a new array with the result of the callback function. This method is good to be used when you need to format the elements of your array.

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

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

reduce - As the name says it reduces the array to a single value by calling the given function passing in the currenct element and the result of the previous execution.

[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 - Returns true or false if all the elements in the array pass the test in the callback function.

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

// Output: false

filter - Very similar to every except that filter return an array with the elements that return true to the given function.

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

// Output: [2,4,6]

Hope this will be useful.




The lambda syntax doesnt usually work in IE 10 or below.

I usually use the

[].forEach.call(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);
});



There isn't any for each loop in native JavaScript . You can either use libraries to get this functionality (I recommend Underscore.js ), use a simple for in loop.

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

However, note that there may be reasons to use an even simpler for loop (see question Why is using “for…in” with array iteration such a bad idea? )

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



Links