arrays تحميل - قم بالالتفاف من خلال صفيف في JavaScript




شرح سكريبت (25)

يمكنك استخدام map ، وهي تقنية برمجة وظيفية متوفرة أيضًا بلغات أخرى مثل Python و Haskell .

[1,2,3,4].map( function(item) {
     alert(item);
})

الصيغة العامة هي:

array.map(func)

بشكل عام ، ستأخذ الدالة func معلمة واحدة ، وهي عنصر من الصفيف. ولكن في حالة JavaScript ، يمكن أن تأخذ معلمة ثانية وهي فهرس العنصر ، ومعلمة ثالثة وهي المصفوفة نفسها.

قيمة الإرجاع من array.map صفيف آخر ، بحيث يمكنك استخدامه مثل هذا:

var x = [1,2,3,4].map( function(item) {return item * 10;});

والآن x هو [10,20,30,40] .

ليس عليك كتابة الدالة المضمنة. يمكن أن يكون وظيفة منفصلة.

var item_processor = function(item) {
      // Do something complicated to an item
}

new_list = my_list.map(item_processor);

والتي قد تكون مكافئة لـ:

 for (item in my_list) {item_processor(item);}

إلا أنك لا تحصل على new_list .

في Java ، يمكنك استخدام حلقة for transverse objects في صفيف كما يلي:

String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray)
{
    // Do something
}

هل يمكنك فعل الشيء نفسه في JavaScript؟


هناك طريقتان للقيام بذلك في JavaScript. المثالان الأولان هما نماذج JavaScript. أما الطريقة الثالثة فتستخدم مكتبة جافا سكريبت ، أي أن jQuery تستخدم هذه .each()الوظيفة.

var myStringArray = ["hello", "World"];
for (var i=0; i < myStringArray.length; i++) {
  alert(myStringArray[i]);
}

var myStringArray = ["hello", "World"];
$.each(myStringArray, function(index, value){
  alert(value);
})

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
var arr = [1, 2, 3, 1023, 1024];
for (var value; value = arr.pop();) {
    value + 1
}


أود أن أوصي تماما الاستفادة من مكتبة underscore.js . يوفر لك الوظائف المختلفة التي يمكنك استخدامها للتكرار عبر المصفوفات / المجموعات.

على سبيل المثال:

_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...

في JavaScript ، هناك العديد من الحلول لحلقة صفيف.

الرمز أدناه هي شعبية

/** Declare inputs */
const items = ['Hello', 'World']

/** Solution 1. Simple for */
console.log('solution 1. simple for')

for (let i = 0; i < items.length; i++) {
  console.log(items[i])
}

console.log()
console.log()

/** Solution 2. Simple while */
console.log('solution 2. simple while')

let i = 0
while (i < items.length) {
  console.log(items[i++])
}

console.log()
console.log()

/** Solution 3. forEach*/
console.log('solution 3. forEach')

items.forEach(item => {
  console.log(item)
})

console.log()
console.log()

/** Solution 4. for-of*/
console.log('solution 4. for-of')

for (const item of items) {
  console.log(item)
}

console.log()
console.log()


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

1. فقط من خلال حلقة صفيف

const myArray = [{x:100}, {x:200}, {x:300}];

myArray.forEach((element, index, array) => {
    console.log(element.x); // 100, 200, 300
    console.log(index); // 0, 1, 2
    console.log(array); // same myArray object 3 times
});

ملاحظة: Array.prototype.forEach () ليست طريقة وظيفية بالمعنى الدقيق للكلمة ، حيث أن الوظيفة التي تتطلبها حيث لا يُفترض أن تقوم معلمة الإدخال بإرجاع قيمة ، وبالتالي لا يمكن اعتبارها دالة نقية.

2. تحقق مما إذا كان أي من العناصر الموجودة في صفيف يمر اختبارًا

const people = [
    {name: 'John', age: 23}, 
    {name: 'Andrew', age: 3}, 
    {name: 'Peter', age: 8}, 
    {name: 'Hanna', age: 14}, 
    {name: 'Adam', age: 37}];

const anyAdult = people.some(person => person.age >= 18);
console.log(anyAdult); // true

3. تحويل إلى مجموعة جديدة

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]

ملاحظة: تقوم طريقة map () بإنشاء صفيف جديد مع نتائج استدعاء دالة مقدمة على كل عنصر في صفيف الاستدعاء.

4. جمع خاصية معينة ، وحساب متوسطها

const myArray = [{x:100}, {x:200}, {x:300}];

const sum = myArray.map(element => element.x).reduce((a, b) => a + b, 0);
console.log(sum); // 600 = 0 + 100 + 200 + 300

const average = sum / myArray.length;
console.log(average); // 200

5. قم بإنشاء مصفوفة جديدة تعتمد على النسخة الأصلية ولكن دون تعديلها

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => {
    return {
        ...element,
        x: element.x * 2
    };
});

console.log(myArray); // [100, 200, 300]
console.log(newArray); // [200, 400, 600]

6. حساب عدد كل فئة

const people = [
    {name: 'John', group: 'A'}, 
    {name: 'Andrew', group: 'C'}, 
    {name: 'Peter', group: 'A'}, 
    {name: 'James', group: 'B'}, 
    {name: 'Hanna', group: 'A'}, 
    {name: 'Adam', group: 'B'}];

const groupInfo = people.reduce((groups, person) => {
    const {A = 0, B = 0, C = 0} = groups;
    if (person.group === 'A') {
        return {...groups, A: A + 1};
    } else if (person.group === 'B') {
        return {...groups, B: B + 1};
    } else {
        return {...groups, C: C + 1};
    }
}, {});

console.log(groupInfo); // {A: 3, C: 1, B: 2}

7. استرجاع مجموعة فرعية من صفيف بناء على معايير معينة

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}] 

ملاحظة: تقوم طريقة filter () بإنشاء مصفوفة جديدة تحتوي على جميع العناصر التي تجتاز الاختبار الذي تم تنفيذه بواسطة الوظيفة المقدمة.

8. فرز صفيف

const people = [
  { name: "John", age: 21 },
  { name: "Peter", age: 31 },
  { name: "Andrew", age: 29 },
  { name: "Thomas", age: 25 }
];

let sortByAge = people.sort(function (p1, p2) {
  return p1.age - p2.age;
});

console.log(sortByAge);

9. البحث عن عنصر في صفيف

const people = [ {name: "john", age:23},
                {name: "john", age:43},
                {name: "jim", age:101},
                {name: "bob", age:67} ];

const john = people.find(person => person.name === 'john');
console.log(john);

إرجاع الأسلوب Array.prototype.find () قيمة العنصر الأول في الصفيف الذي يفي الدالة اختبار المقدمة.

المراجع


هناك طريقة مختلفة للحلقة عبر الصفيف في JavaScript.

حلقة عامة:

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

ES5 في forEach:

substr.forEach(function(item) {
    // Do something with `item`
});

jQuery.each:

jQuery.each(substr, function(index, item) {
    // Do something with `item` (or `this` is also `item` if you like)
});

إلقاء نظرة على this للحصول على معلومات مفصلة أو يمكنك أيضا التحقق من for...in لحلقات من خلال صفيف في جافا سكريبت واستخدام jQuery تحقق jQuery.each() .


لـ (var s of myStringArray) {

(الإجابة مباشرة على سؤالك: يمكنك الآن!)

معظم الإجابات الأخرى صحيحة ، لكنهم لا يذكرون (حتى كتابة هذه السطور) أن ECMA Script 6 2015 يجلب آلية جديدة للقيام بالتكرار ، من for..of حلقة.

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

يعمل حاليًا مع Firefox 13+ و Chrome 37+ ولا يعمل مع متصفحات أخرى (راجع توافق المتصفح أدناه). لحسن الحظ لدينا مترجمون JS (مثل Babel ) التي تسمح لنا باستخدام ميزات الجيل التالي اليوم.

كما أنه يعمل على عقدة (لقد اختبرت ذلك على الإصدار 0.12.0).

تكرار صفيف

// You could also use "let" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) { 
   console.log(letter); 
}

تكرار مجموعة من الكائنات

var band = [
  {firstName : 'John', lastName: 'Lennon'}, 
  {firstName : 'Paul', lastName: 'McCartney'}
];

for(var member of band){
  console.log(member.firstName + ' ' + member.lastName); 
}

تكرار مولد:

(تم استخراج هذا المثال من https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of )

function* fibonacci() { // a generator function
  let [prev, curr] = [1, 1];
  while (true) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (let n of fibonacci()) {
  console.log(n);
  // truncate the sequence at 1000
  if (n >= 1000) {
    break;
  }
}

جدول التوافق: http://kangax.github.io/es5-compat-table/es6/#For..of من الحلقات

المواصفات: http://wiki.ecmascript.org/doku.php?id=harmony:iterators

}


إذا كنت تريد استخدام jQuery ، فلديها مثال جيد في وثائقها:

 $.each([ 52, 97 ], function( index, value ) {
      alert( index + ": " + value );
 });

حلقة الصفيف:

for(var i = 0; i < things.length; i++){
    var thing = things[i];
    console.log(thing);
}

حلقة كائن:

for(var prop in obj){
    var propValue = obj[prop];
    console.log(propValue);
}

استخدام تسلسلي للحلقة:

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

يقترح @ zipcodeman استخدام من for...in العبارة ، ولكن لتكرار صفائف for-in يجب تجنبها ، المقصود من تلك العبارة تعداد خصائص الكائن.

يجب ألا يتم استخدامه مع كائنات شبيهة بالمصفوفة بسبب:

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

النقطة الثانية هي أنه يمكن أن يوفر لك الكثير من المشاكل ، على سبيل المثال ، إذا قمت بتوسيع كائن Array.prototype لتضمين أسلوب هناك ، سيتم أيضاً تعداد تلك الخاصية.

فمثلا:

Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];

for (var i in array) {
  alert(array[i]);
}

سوف ينبّه الرمز أعلاه "a" و "b" و "c" و "foo!".

تكون هذه مشكلة خاصة إذا كنت تستخدم بعض المكتبات التي تعتمد بشكل كبير على زيادة النماذج الأصلية (مثل MooTools على سبيل المثال).

العبارة for-in كما قلت من قبل موجودة لتعداد خصائص الكائن ، على سبيل المثال:

var obj = {
  "a": 1,
  "b": 2,
  "c": 3
};

for (var prop in obj) {
  if (obj.hasOwnProperty(prop)) { 
  // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
    alert("prop: " + prop + " value: " + obj[prop])
  }
}

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

أنصحك بقراءة المقالة التالية:


تشترك الآن Opera و Safari و Firefox و Chrome الآن في مجموعة من طرق Array المحسّنة لتحسين العديد من الحلقات الشائعة.

قد لا تحتاج إلى كل هذه العناصر ، ولكنها قد تكون مفيدة جدًا ، أو قد تكون متوفرة إذا كان كل متصفح يدعمها.

قامت Mozilla Labs بنشر الخوارزميات التي تستخدمها و WebKit حد سواء ، بحيث يمكنك إضافتها بنفسك.

عامل التصفية بإرجاع مجموعة من العناصر التي تفي ببعض الشروط أو الاختبار.

كل العوائد صحيح إذا اجتاز كل عضو صفيف الاختبار.

يعود بعض صحيح إذا نجح أي اختبار.

forEach يعمل على وظيفة كل عضو صفيف ولا يعيد أي شيء.

الخريطة مثل forEach ، لكنها تُرجع مصفوفة من نتائج العملية لكل عنصر.

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

تجاهلها حتى تحتاجها.

indexOf و lastIndexOf العثور على الموضع المناسب للعنصر الأول أو الأخير الذي يتطابق مع الوسيطة بالضبط.

(function(){
    var p, ap= Array.prototype, p2={
        filter: function(fun, scope){
            var L= this.length, A= [], i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        val= this[i];
                        if(fun.call(scope, val, i, this)){
                            A[A.length]= val;
                        }
                    }
                    ++i;
                }
            }
            return A;
        },
        every: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && !fun.call(scope, this[i], i, this))
                        return false;
                    ++i;
                }
                return true;
            }
            return null;
        },
        forEach: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
            }
            return this;
        },
        indexOf: function(what, i){
            i= i || 0;
            var L= this.length;
            while(i< L){
                if(this[i]=== what)
                    return i;
                ++i;
            }
            return -1;
        },
        lastIndexOf: function(what, i){
            var L= this.length;
            i= i || L-1;
            if(isNaN(i) || i>= L)
                i= L-1;
            else
                if(i< 0) i += L;
            while(i> -1){
                if(this[i]=== what)
                    return i;
                --i;
            }
            return -1;
        },
        map: function(fun, scope){
            var L= this.length, A= Array(this.length), i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        A[i]= fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
                return A;
            }
        },
        some: function(fun, scope){
            var i= 0, L= this.length;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && fun.call(scope, this[i], i, this))
                        return true;
                    ++i;
                }
                return false;
            }
        }
    }
    for(p in p2){
        if(!ap[p])
            ap[p]= p2[p];
    }
    return true;
})();

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

let arr = [1,2,3,4,5];

for(let i=0, size=arr.length; i<size; i++){
    // do something
}

لكنه سيظل متكرراً على خصائص محددة معرفة.

في javascript ، يمكن تعيين أي خاصية مخصصة لأي كائن بما في ذلك الصفيف.

إذا كان أحد يريد تكرار عبر مجموعة sparsed، for (var i = 0; i < array.length; i++) if (i in array)أو array.forEachمع es5shimينبغي استخدامها.


نعم ، ولكن فقط إذا تضمن التنفيذ الخاص بك ... للميزة المقدمة في ECMAScript 2015 (إصدار "التناغم").

يعمل مثل هذا:

// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
  // ... do something with s ...
}

أو الأفضل من ذلك ، حيث أن ECMAScript 2015 يوفر أيضًا متغيرات النطاق عبر const and const :

// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
  // ... do something with s ...
}
// s is no longer defined here

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

إذا استطعت أن تفترض أن مترجم JavaScript متوافق مع الإصدار السابق من مواصفات ECMAScript (الذي يستبعد ، على سبيل المثال ، إصدارات Internet Explorer قبل 9) ، فيمكنك استخدام أسلوب forEach iterator بدلاً من حلقة. في هذه الحالة ، يمكنك تمرير دالة ليتم استدعاؤها على كل عنصر في الصفيف:

var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) { 
     // ... do something with s ...
} );

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

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  if (i in myStringArray) {
    s = myStringArray[i];
    // ... do something with s ...
  }
}

يمكن أن يؤدي تعيين قيمة الطول للمتغير المحلي ( myStringArray.length عن myStringArray.length تعبير myStringArray.length الكامل في حالة الحلقة) إلى حدوث اختلاف كبير في الأداء حيث يتخطى البحث عن خاصية في كل مرة خلال؛ باستخدام الكركدن على الجهاز الخاص بي ، تسريع هو 43 ٪.

ستشاهد في أغلب الأحيان التخزين المؤقت للطول الذي تم تنفيذه في جملة تهيئة الحلقة ، كما يلي:

var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {

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


على سبيل المثال ، لقد استخدمت في وحدة تحكم Firefox:

[].forEach.call(document.getElementsByTagName('pre'), function(e){ 
   console.log(e);
})

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

var arr = [1, 2, 3, 4, 5];

هذه هي الحلول:

1) للحلقة

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

for (var i=0, l=arr.length; i<l; i++) { 
  console.log(arr[i]);
}

2) في حين حلقة

في حين تعتبر الحلقة الطريقة الأسرع للحلقة عبر المصفوفات الطويلة ، ولكن عادة ما تكون أقل استخدامًا في JavaScript:

let i=0;

while (arr.length>i) {
    console.log(arr[i]);
    i++;
}

3)
القيام به في حين تفعل نفس الشيء مع بعض الاختلافات في النحو النحو التالي:

let i=0;
do {
  console.log(arr[i]);
  i++;
}
while (arr.length>i);

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

كما نستخدم for inحلقة للتكرار فوق الكائنات في javascript.

انظر أيضا map()، filter()، reduce()الخ وظائف في صفيف في جافا سكريبت. قد يفعلون أشياء أسرع بكثير وأفضل من استخدام whileو for.

هذه مقالة جيدة إذا كنت ترغب في معرفة المزيد عن وظائف المتزامن عبر المصفوفات في JavaScript.

لقد جعلت البرمجة الوظيفية دفقة في عالم التطوير هذه الأيام. ولأسباب وجيهة: يمكن أن تساعدك التقنيات الوظيفية على كتابة المزيد من الكود التعريفي الذي يسهل فهمه بلمحة ونظافة واختبار.

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

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

وهذا يعني أيضًا أنك لن تضطر أبدًا إلى كتابة حلقة for مرة أخرى.

اقرأ المزيد >> here :


هناك طريقة للقيام بذلك حيث يكون لديك نطاقًا ضئيلًا جدًا في حلقتك وتخلص من المتغيرات الإضافية.

var i = 0,
     item;

// note this is weak to sparse arrays or falsey values
for ( ; item = myStringArray[i++] ; ){ 
    item; // This is the string at the index.
}

أو إذا كنت تريد حقًا الحصول على المعرّف ولديك حلقة كلاسيكية for حقًا:

var i = 0,
    len = myStringArray.length; // cache the length

for ( ; i < len ; i++ ){
    myStringArray[i]; // Don't use this if you plan on changing the length of the array
}

تدعم جميع المتصفحات الحديثة أساليب التكرار forEach ، map ، reduce ، filter ، ومجموعة من الطرق الأخرى في النموذج الأولي forEach .


إذا كنت تريد طريقة مقطوعة لكتابة حلقة سريعة ويمكنك التكرار في الاتجاه المعاكس:

for (var i=myArray.length;i--;){
  var item=myArray[i];
}

هذا له فائدة من التخزين المؤقت للطول (مماثل for (var i=0, len=myArray.length; i<len; ++i) وعلى عكس for (var i=0; i<myArray.length; ++i) ) بينما تكون الأحرف أقل للكتابة.

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


var x = [4, 5, 6];
for (i = 0, j = x[i]; i < x.length; j = x[++i]) {
    console.log(i,j);
}

منظف ​​كثير ...


مقدمة

منذ أن قضيت دراستي الجامعية ، قمت ببرمجة في Java ، و JavaScript ، و Pascal ، و ABAP ، و PHP ، و Progress 4GL ، و C / C ++ ، وربما بعض اللغات الأخرى التي لا أستطيع التفكير بها الآن.

في حين أن جميعهم لديهم خصوصيات لغوية خاصة بهم ، فإن كل لغة من هذه اللغات تتشارك في العديد من المفاهيم الأساسية نفسها. تتضمن هذه المفاهيم الإجراءات / الدالات ، IF -statements ، FOR -lops ، و WHILE -loops.

التقليدية لقلوب

تحتوي الحلقة التقليدية for ثلاثة مكونات:

  1. التهيئة: يتم تنفيذها قبل تنفيذ كتلة المظهر في المرة الأولى
  2. الشرط: يتحقق من الشرط في كل مرة قبل تنفيذ كتلة الحلقة ، ويتم إنهاء الحلقة إذا كانت خاطئة
  3. المفكرة المتأخرة: يتم تنفيذها في كل مرة بعد تنفيذ كتلة الحلقة

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

for (;;) {
    // Do stuff
}

بالطبع ، سوف تحتاج إلى تضمين if(condition === true) { break; } if(condition === true) { break; } أو if(condition === true) { return; } if(condition === true) { return; } مكان ما داخل ذلك -للحصول على إيقاف تشغيله.

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

for (var i = 0, length = 10; i < length; i++) {
    console.log(i);
}

استخدام حلقة تقليدية للحلقة عبر صفيف

الطريقة التقليدية للحلقة عبر صفيف ، هي:

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

أو ، إذا كنت تفضل التكرار إلى الخلف ، فيمكنك إجراء ذلك:

for (var i = myArray.length - 1; i > -1; i--) {
    console.log(myArray[i]);
}

ومع ذلك ، هناك العديد من الاختلافات الممكنة ، على سبيل المثال ، هذه الاختلافات:

for (var key = 0, value = myArray[key], length = myArray.length; key < length; value = myArray[++key]) {
    console.log(value);
}

... ما سر جديدة هذا ...

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

... ما سر جديدة هذا:

var key = 0, value;
for (; value = myArray[key++];){
    console.log(value);
}

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

لاحظ أن كل هذه الأشكال تدعمها جميع المتصفحات ، بما في ذلك المتصفحات القديمة جدًا!

حلقة في while

بديل واحد للحلقة هو حلقة في while . للحلقة عبر صفيف ، يمكنك القيام بذلك:

var key = 0;
while(value = myArray[key++]){
    console.log(value);
}

مثل التقليدية للحلقات ، في while الحلقات تدعمها حتى أقدم المتصفحات.

لاحظ أيضًا أنه في كل مرة يمكن إعادة كتابة حلقة كـ حلقة for . على سبيل المثال ، تتصرف حلقة while hereabove بالطريقة نفسها تمامًا مثل: tololoove:

for(var key = 0; value = myArray[key++];){
    console.log(value);
}

For...in for...of

في JavaScript ، يمكنك أيضًا القيام بذلك:

for (i in myArray) {
    console.log(myArray[i]);
}

ومع ذلك ، يجب استخدام هذا بعناية ، حيث أنه لا يتصرف بنفس الطريقة التقليدية في جميع الحالات ، وهناك آثار جانبية محتملة يجب أخذها بعين الاعتبار. راجع لماذا يستخدم "for ... in" مع تكوين الصفيف فكرة سيئة؟ لمزيد من التفاصيل.

كبديل for...in ، هناك الآن أيضا من https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of . يوضح المثال التالي الفرق بين a for...of loop و for...in حلقة:

var myArray = [3, 5, 7];
myArray.foo = "hello";

for (var i in myArray) {
  console.log(i); // logs 0, 1, 2, "foo"
}

for (var i of myArray) {
  console.log(i); // logs 3, 5, 7
}

بالإضافة إلى ذلك ، يجب الأخذ في الاعتبار أنه لا يوجد إصدار من Internet Explorer يدعم for...of ( الحافة 12+ لا) ويتطلب ذلك في ما لا يقل عن Internet Explorer 10.

Array.prototype.forEach()

بديل for forlolo هو Array.prototype.forEach() ، والذي يستخدم بناء الجملة التالي:

myArray.forEach(function(value, key, myArray) {
    console.log(value);
});

Array.prototype.forEach() معتمد من قبل جميع المتصفحات الحديثة ، وكذلك Internet Explorer 9 والإصدارات الأحدث.

المكتبات

وأخيرًا ، فإن العديد من مكتبات المرافق لديها أيضًا تنوعها الخاص. AFAIK ، الثلاثة الأكثر شعبية هي:

jQuery.each() ، في jQuery :

$.each(myArray, function(key, value) {
    console.log(value);
});

_.each() ، في Underscore.js :

_.each(myArray, function(value, key, myArray) {
    console.log(value);
});

_.forEach() ، في Lodash.js :

_.forEach(myArray, function(value, key) {
    console.log(value);
});

الطريقة الأكثر أناقة وسرعة

<script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<script>
    Benchmark.prototype.setup = function() {
        // Fake function with minimal action on the value
        var tmp = 0;
        var process = function(value) {
            tmp = value; // Hold a reference to the variable (prevent engine optimisation?)
        };

        // Declare the test Array
        var arr = [];
        for (var i = 0; i < 100000; i++)
            arr[i] = i;
    };
</script>

http://jsperf.com/native-loop-performance/8

تم التعديل (لأنني كنت مخطئا)

مقارنة طرق التكرار من خلال مجموعة من 100000 عنصر والقيام بأقل عملية مع القيمة الجديدة في كل مرة.

تجهيز:

<a href="http://jsperf.com/native-loop-performance/16" 
   title="http://jsperf.com/native-loop-performance/16"
><img src="http://i.imgur.com/YTrO68E.png" title="Hosted by imgur.com" /></a>

الاختبارات:

for (var i in array) if (array.hasOwnProperty(i)) {
    // do something with array[i]
}

لم ألاحظ حتى الآن هذا الشكل ، الذي أحبه شخصيًا أفضل:

أعطى مجموعة:

var someArray = ["some", "example", "array"];

يمكنك تكرارها دون الدخول إلى خاصية الطول مطلقًا:

for (var i=0, item; item=someArray[i]; i++) {
  // item is "some", then "example", then "array"
  // i is the index of item in the array
  alert("someArray[" + i + "]: " + item);
}

شاهد هذا JsFiddle مما يدل على: http://jsfiddle.net/prvzk/

يعمل هذا فقط مع المصفوفات غير المتقطعة. بمعنى أن هناك بالفعل قيمة في كل فهرس في الصفيف. ومع ذلك ، وجدت أنه من الناحية العملية ، نادراً ما أستخدم صفائف متفرقة في Javascript ... في مثل هذه الحالات يكون من الأسهل كثيرًا استخدام كائن كخريطة / hashtable. إذا كان لديك مصفوفة متفرقة ، وتريد التكرار أكثر من 0 .. length-1 ، فأنت تحتاج إلى تكوين (var i = 0؛ i <someArray.length؛ ++ i) ، ولكنك ما زلت بحاجة إلى ما إذا كان داخل حلقة للتحقق ما إذا كان العنصر الموجود في الفهرس الحالي محددًا بالفعل أم لا.

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

ما يعجبني في هذه الحلقة هو:

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

والسبب في ذلك هو أن مواصفات الصفيف تنص على أنه عندما تقرأ عنصرًا من فهرس> = طول الصفيف ، فإنه سيعود غير محدد. عندما تكتب إلى مثل هذا الموقع ، ستقوم بالفعل بتحديث الطول.

بالنسبة لي ، يحاكي هذا البناء عن كثب بنية جافا 5 التي أحبها:

for (String item : someArray) {
}

... مع فائدة إضافية من معرفة أيضا عن الفهرس الحالي داخل الحلقة


أفضل طريقة في رأيي هي استخدام الدالة Array.forEach. إذا لم يكن باستطاعتك استخدام ذلك ، فإنني أقترح الحصول على polyfill من MDN لتوفير i ، وهي بالتأكيد الطريقة الأسلم للتكرار عبر صفيف في JavaScript.

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

كما اقترح الآخرون ، هذا دائمًا ما تريده تقريبًا:

var numbers = [1,11,22,33,44,55,66,77,88,99,111];
var sum = 0;
numbers.forEach(function(n){
  sum += n;
});

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

باستخدام نمط c عادي لحلقة العمل في معظم الحالات ، من المهم فقط تذكر أن كل شيء داخل الحلقة هو نطاقه مع باقي البرنامج ، لا يقوم {} بإنشاء نطاق جديد.

بالتالي:

var sum = 0;
var numbers = [1,11,22,33,44,55,66,77,88,99,111];

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

alert(i);

سوف يخرج "11" - والتي قد تكون أو لا تكون ما تريده.

مثال jsFiddle العامل: https://jsfiddle.net/workingClassHacker/pxpv2dh5/7/


إجابة مختصرة: نعم. يمكنك القيام بذلك:

var myArray = ["element1", "element2", "element3", "element4"];

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

في وحدة تحكم المستعرض ، يمكنك رؤية شيء مثل "element1" ، "element2" ، وما إلى ذلك ، مطبوعًا.


إذا كنت تستخدم مكتبة jQuery ، ففكر في استخدام http://api.jquery.com/jQuery.each/

من الوثائق:

jQuery.each( collection, callback(indexInArray, valueOfElement) )

إرجاع: كائن

الوصف: وظيفة مكرر عام ، والتي يمكن استخدامها للتكرار بسلاسة عبر الكائنات والمصفوفات. يتم تكرار صفائف و كائنات شبيهة بخاصية الطول (مثل كائن وسائط الدالة) بواسطة فهرس رقمي ، من 0 إلى الطول -1. يتم تكرار الكائنات الأخرى عبر خصائصها المسماة.

و $.each()ظيفة ليست هي نفسها كما $(selector).each()، والذي يستخدم لتكرار، حصرا، على الجسم مسج. و $.each()ظيفة يمكن أن تستخدم لتكرار عبر أي جمع، سواء كانت خريطة (كائن جافا سكريبت) أو صفيف. في حالة صفيف ، يتم تمرير رد الاتصال بفهرس صفيف وقيمة صفيف مناظر في كل مرة. (يمكن الوصول إلى القيمة أيضًا من خلال thisالكلمة الأساسية ، ولكن ستقوم Javascript دائمًا بلف thisالقيمة كقيمة Objectحتى إذا كانت قيمة سلسلة أو رقم بسيطة.) تقوم الطريقة بإرجاع الوسيطة الأولى ، الكائن الذي تم تشغيله.


تكمن المشكلة في التعليمة البرمجية في أن جافا سكريبت حساس لحالة الأحرف. استدعاء الأسلوب الخاص بك

indexof()

يجب أن يكون في الواقع

indexOf()

جرّب إصلاحه ومعرفة ما إذا كان ذلك يساعد على:

if (test.indexOf("title") !=-1) {
    alert(elm);
    foundLinks++;
}




javascript arrays loops for-loop