From irritation to iteration #2
A short iteration over Iteration functions
After covering the iteration basic concept on From irritation to iteration #1, it’s time for a short overview of all the array iteration methods we have. To make it simpler, I grouped similar functions with a line.
forEach
The forEach is the fastest way iterate. It executes the function over each element and doesn’t return a thing.
let arr = [1,2,3] let arr2 = arr.forEach((item,index) => { item++; }); // arr = [1,2,3] // arr2 = undefined let arr = [{v:1},{v:2},{v:3}]; arr.forEach((item,index) => { item.v++; }); // arr ==> [{v:2},{v:3},{v:4}]
map
Create a transformation copy of each element from an array. Covered in length on the post about JavaScript array map.
[1,2,3].map((x)=>{ return x * x; }); // returns: 1,4,9
Find
Return the first true condition. If none of the condition is true, will return undefined. The iteration will exit the loop on the first true value. Null values are not skipped.
"sleep" === ['Ariel','wants','to','sleep',,'not','skip'].find(item => item[0] == 's'); undefuned === ['Ariel','wants','to','sleep','not','skip'].find(item => item == 'eat')
['Ariel','wants','to',,'not','skip'].find(item => item[1] == 's') // Uncaught TypeError: Cannot read property '1' of undefined
findIndex
The same as “find”, just instead of the value, return the index. If no value had been found, it returns -1;
1 === ['to','sleep'].findIndex(item => item == 'sleep'); -1 === ['to','sleep'].findIndex(item => item == 'eat');
every
Checks if all the elements answer the condition:
true === ["zas","zad","zaf"].every((x) => x[1] == 'a'); false === ["zas","zzz","zaf"].every((x) => x[1] == 'a');
Exit the loop on first false value:
false === [{b:{c:1}},{},{b:{c:2}}].every((item,index) => { return item.b.c > 3; });
Ignores null values
true === ["zaz",,"zaf"].every((x) => x[1] == 'a');
But falls on errors
[{b:{c:5}},{},{b:{c:2}}].every((item,index) => { return item.b.c > 3; });
some
Same as “every”, check if at least one of the elements answer the condition. That’s why it stops on the first true value.
true === [{b:{c:5}},{},{b:{c:2}}].some((item,index) => { return item.b.c > 3; });
Filter
Return a new set of elements that pass the condition.
arr = [1,2,3,4,5,6] arr.filter((value) => { return value < 3; }); // [1,2] let me = [{name:'me',works:'overtime'},{name:'someone else',works:'less'}].filter((value) => { return value.works =='overtime'; });
reduce / reduceRight
Finally a different case: the reduction goes over each item, but also passes the result of the previously returned value. This way you can create a function like SUM on lists.
[1,2,3,4,5].reduce((accumulator,currentItem,index,array) => { console.log(index + ': ' + accumulator + ' + ' + currentItem); return accumulator + currentItem; }); //1: 1 + 2 //2: 3 + 3 //3: 6 + 4 //4: 10 + 5 // returns 15
If can pass the accumulator with starting value:
[1,2,3,4,5].reduce((accumulator,currentItem,index) => { console.log(index + ': ' + accumulator + ' + ' + currentItem); return accumulator + currentItem; },100); //0: 100 + 1 //1: 101 + 2 //2: 103 + 3 //3: 106 + 4 //4: 110 + 5 //115
Since it compares only the two values: the result and the current, we can do…
arr.reduce((accumulator,currentItem) => { return Math.max(accumulator,currentItem); });
And just if you want to start from the end of the array and go backward:
[1,2,3,4,5].reduce((a,b,c,d) => { return a+ b; },'0'); // 012345 [1,2,3,4,5].reduceRight((a,b,c,d) => { return a+ b; },'0'); // 054321
entries
Return iterator of key-value objects
arr = ['a','b'] var iterator = arr.entries(); for (let[index, value] of iterator) { console.log(index + ': ' + value); } //0: a //1: b
values
Return iterator, but without the index.
let array = [2,3,,5]; let iterator = array.values(); console.log(...iterator); // 2 3 undefined 5 array = new Array(5); console.log(...array.values()); // undefined undefined undefined undefined undefined array = new Array(); array[3] = 'd'; console.log(...array.values()); // undefined undefined undefined "d"
keys
gets the keys of the array to include empty elements
let array = [2,3,,5]; let iterator = array.keys(); console.log(...iterator); // 0 1 2 3 array = new Array(5); console.log(...array.keys()) // 0 2 3 4 array = new Array(); array[9] = 'd'; console.log(...array.keys()) // 0 1 2 3 4 5 6 7 8 9
I’ll be happy to get a useful example for all the last three :-/
Conclusion
The iteration was longer than expected, but It’s useful to know about the different options. Some are cool, some useful, and some are meant to satisfy the evil spirits. The last type is not documented in the post, but they are always there. Believe me, they are always there.