javascript - معلم - ما هي لغة java script




قم بالالتفاف من خلال صفيف في JavaScript (20)

لـ (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

}

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

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

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


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

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

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

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

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

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

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 أثناء التكرار.


استخدم حلقة while ...

var i=0, item, items = ['one','two','three'];
while(item = items[i++]){
    console.log(item);
}

السجلات: "واحد" ، "اثنين" ، "ثلاثة"

وللترتيب العكسي ، حلقة أكثر كفاءة

var items = ['one','two','three'], i = items.length;
while(i--){
    console.log(items[i]);
}

السجلات: "ثلاثة" ، "اثنين" ، "واحد"

أو الكلاسيكية للحلقة

var items = ['one','two','three']
for(var i=0, l = items.length; i < l; i++){
    console.log(items[i]);
}

السجلات: "واحد" ، "اثنين" ، "ثلاثة"

المرجع: http://www.sitepoint.com/google-closure-how-not-to-write-javascript/


تستخدم بعض حالات التكرار من خلال صفيف بطريقة البرمجة الوظيفية في 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 ، لا يُنصح بالربط من خلال Array باستخدام حلقة for-in ، ولكن من الأفضل استخدام حلقة for مثل:

for(var i=0, len=myArray.length; i < len; i++){}

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


نعم ، ولكن فقط إذا تضمن التنفيذ الخاص بك ... للميزة المقدمة في 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 بناء الجملة من أجل التكرار خلال صفائف.


هناك طريقة مختلفة للحلقة عبر الصفيف في 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() .


يمكنك استخدام 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 .


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

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

انها ليست متطابقة 100 ٪ ، ولكنها مماثلة:

   var myStringArray = ['Hello', 'World']; // array uses [] not {}
    for (var i in myStringArray) {
        console.log(i + ' -> ' + myStringArray[i]); // i is the index/key, not the item
    }


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

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

في 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()


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

var myStringArray = ["Hello","World"];
myStringArray.forEach(function(f){
    // Do something
})

نعم ، يمكنك أن تفعل الشيء نفسه في 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 الفردي الذي يقوم بتهيئة جميع المتغيرات بكلمة 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]
}

أفضل طريقة في رأيي هي استخدام الدالة 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/


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

من الوثائق:

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

إرجاع: كائن

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

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


هناك طريقتان للقيام بذلك في 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
}





for-loop