Creating a limited array with custom methods - javascript

I want to create a helper object that will work the following way:
It is an array with a given number of rows, for example let's say it can hold only 3 rows.
It will have an insert method that inserts the a new entry at the first index, and pushes one index down all the rest (new entry is 0, 0 becomes 1, 1-->2 etc..)
and if the array is full to the max number of rows, the last entry drops out.
So I made it the following way:
function limArray(array, maxlength){
this.arr = array;
this.maxlength = maxlength;
this.arr.length = maxlength;
this.insertVal = function(value){ //insert new value and push down the rest
for (var i=maxlength; i>=0; i--) {
this.arr[i] = this.arr[i-1]
};
this.arr[0] = value;
this.arr.length = maxlength;
};
}
My question is, if it's a smart way to make this?
Is it possible to create instance of the Array object itself and modify it to be limited etc..
Any critique / improvement suggestions are welcome!

You could overwrite the push method:
function limArray(array, maxlength){
var push_ = array.push,
slice_ = [].slice;
array.push = function() {
var values = slice_.call(arguments, 0, maxlength - this.length);
return push_.apply(this, values);
}
return array;
}
As #alnorth29 mentioned, you can use unshift to prepend a value. You can overwrite this as well:
function limArray(array, maxlength){
// push like above
var unshift_ = array.unshift;
array.unshift = function() {
unshift_.apply(this, arguments);
this.length = this.length > maxlength ? maxlength : this.length;
return this.length;
}
return array;
}
Of course you can also attach a new property with a more expressive name than unshift:
array.prepend = array.unshift;
If you extend an array instance like this, make sure you only traverse over its elements with a for loop, not with a for...in loop (you should always use for for arrays anyway). Another possibility is to define the property using ECMAScript 5's Object.defineProperty [docs] and set enumerable to false. But it is only supported in newer browsers.
There are other ways to add elements to an array, but I assume you are not going to use them .
Usage:
> var limited = limArray([], 3);
> limited.push(1,2,3,4);
3
> limited
[1, 2, 3]
> limited.push(5)
3
> limited
[1, 2, 3]
> var limited = limArray([], 3);
> limited.unshift(3, 4)
2
> limited
[3, 4]
> limited.unshift(1, 2)
3
> limited
[1, 2, 3]
Update:
I forgot, in case the array passed to the function already exceeds the maximum number of elements, you have to reduce the length:
function limArray(array, maxlength){
array.length = array.length > maxlength ? maxlength : array.length;
//...
return array;
}

This looks fine to me, though you could use the array's unshift method to add values to the start of the array rather than manually updating all of them. This would make it more compact.
function limArray(array, maxlength){
this.arr = array;
this.maxlength = maxlength;
this.arr.length = maxlength;
this.insertVal = function(value){ //insert new value and push down the rest
this.arr.unshift(value);
this.arr.length = maxlength;
};
}
As far as I know there's no built in way for defining the maximum length of an array.

Related

removeDuplicates does not work as expected

I am trying to extend Array prototype with the following functions:
Array.prototype.uniqueItems=function(){
var ar=this,unique=[],max=ar.length;
for(var i = 0 ; i < max;i++)
if(unique.indexOf(ar[i] )==-1)
unique.push(ar[i]);
return unique;
};
Array.prototype.removeDuplicates=function(){
var self = this;
self = this.uniqueItems();
return self;
};
The first function is supposed to return an array without duplicates and the second to remove all duplicates from a given array.
Consider the following code:
var x=[1,1,1,1,2,2,2,2,3,3,3,3,4,4];
x.removeDuplicates();
console.log(x);
The output is :
[ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4 ]
So the duplicates still remain.Any ideas why?Thanks In advance!!!!Also notice that I can not use x= x.uniqueItems() since it will work only for x.I want it to work for any given array.
You might as well do it like this in ES6
var x = [1,1,1,1,2,2,2,2,3,3,3,3,4,4],
u = a => Array.from(new Set(a)),
y = u(x);
console.log(y);
The new Set object in ES6 takes elements and keeps only one of each and discard the dupes. So it's in a way ideal to get unique items. A new set object is instantitated by the Set constructor and it will accept an array of items as an argument such as in var s = new Set([1,1,2,1,4,3,6,7,4,5,6,9,8,1,2,3,4,7,0]) and the resulting s set will be composed of unique entries of 1,2,4,3,6,7,5,9,8 and 0 in the order of appearance. Set objects have generator properties and iterator functions which can be obtained from them. Hence [...s] (the ES6 spread operator) or Array.from(s) would result a proper unique items array automatically.
Converting the Array to a Set and back allows for an arguably cleaner implementation:
Array.prototype.uniqueItems = function() {
return new Array.from(new Set(this));
};
Array.prototype.removeDuplicates = function() {
this.from(new Set(this));
};
Reassign to x.
var x=[1,1,1,1,2,2,2,2,3,3,3,3,4,4];
x = x.removeDuplicates();
console.log(x);
when you say
self = this.uniqueItems();
self is now pointing to a new array, not this
You need to either do
x = x.removeDuplicates();
or iterate this again in removeDuplicates to remove the other items.
For example
Array.prototype.removeDuplicates=function(){
var self = this;
var that = this;
self = this.uniqueItems();
//remove all items
for(var counter = that.length ; counter >= 0; counter -- )
{
that.splice(counter,1);
}
//copy the individual items to this
Object.keys(self).forEach(function(index){
that[index] = self[index]
});
return self;
};
Hey thank you all for your answers .I found a simple solution to my problem by doing the following:
Array.prototype.removeDuplicates=function(){
//First create a copy of the current array without duplicates
var clear_array=this.uniqueItems();
//Delete every item in the current array
this.length=0;
//Fill the current array with the elements of clear_array
for(var i = 0;i<clear_array.length;i++)
this[i] = clear_array[i];
return this;
};
Also I did not use a Set since I want to be sure about backwards compatibility
Hope this will be helpful to someone :)

Remove and store an array item without creating garbage

I'm looking for a performant way to remove and store elements from an array. I am trying to make an object pool to reduce garbage collections calls.
Just as .pop() and .unshift() remove elements from an array and return the value of that element, I'd like to be able to remove an element at a specific index, while storing it's value in a variable, and while not creating unnecessary arrays/objects.
.splice() removes the element at a specific index just fine, and stores that value in an array. I can access that, but the function itself creates a new array, which will eventually trigger the garbage collector.
.slice() has the same issue, a new array is created.
Is there a way to pull out and store a specific indexed element without the creation of a new array?
This always removes one item at index, if you need to remove more than 1 consecutive items at a time, it would be
more efficient to implement it to take a howMany argument and remove them in a batch instead of calling
removeAt repeatedly.
function removeAt(array, index) {
// Assumes array and index are always valid values
// place validation code here if needed
var len = array.length;
// for example if index is not valid here, it will deoptimize the function
var ret = array[index];
for (var i = index + 1; i < len; ++i) {
array[i - 1] = array[i];
}
array.length = len - 1;
return ret;
}
Usage:
var a = [1,2,3,4,5]
var removed = removeAt(a, 2);
console.log(a);
// [1, 2, 4, 5]
console.log(removed);
// 3

Javascript: How to clear undefined values from an array

I'm trying to loop through an array and delete and skip the elements until only one is existing. i've tried splicing but it messes up my loop because the element from arr[1] then becomes arr[0] etc.
Let's say there are 10 people. I'd like to remove person 1 then keep person 2 then remove person 3 and keep person 4. This pattern will go on until only one is left.
any kind of help will do.
Filter the falsy items:
var a=[1,2,"b",0,{},"",NaN,3,undefined,null,5];
var b=a.filter(Boolean); // [1,2,"b",{},3,5]
you should not change the collection during the iterating, not just JavaScript but all language, define a new array and add those ones you want to delete in it, and iterate that one later to delete from first one.
When you splice, just decrement your loop index.
There were lots of good suggestions, I'll post the code for the different options and you can decide which to use
Decrement index when splicing
http://jsfiddle.net/mendesjuan/aFvVh/
var undef;
var arr = [1,2, undef, 3, 4, undef];
for (var i=0; i < arr.length; i++) {
if ( arr[i] === undef ) {
arr.splice(i,1);
i--;
}
}
Loop backwards http://jsfiddle.net/mendesjuan/aFvVh/1/
var undef;
var arr = [1,2, undef, 3, 4, undef];
for (var i=arr.length - 1; i >=0; i--) {
if ( arr[i] === undef ) {
arr.splice(i,1);
}
}
Copy to new array http://jsfiddle.net/mendesjuan/aFvVh/2/
var undef;
var arr = [1,2, undef, 3, 4, undef];
var temp = [];
for (var i=0; i < arr.length; i++) {
if ( arr[i] !== undef ) {
temp.push(arr[i])
}
}
arr = temp;
Use filter which is just a fancy way to create a new array
var undef;
var arr = [1,2, undef, 3, 4, undef];
arr = arr.filter(function(item){
return item !== undef;
});
At the end of all those examples, arr will be [1,2,3,4]
Performance
IE 11, FF and Chrome agree that Array.splice is the fastest. 10 times (Chrome), 20 times (IE 11) as fast as Array.filter. Putting items into a new array was also slow when compared to Array.slice. See
http://jsperf.com/clean-undefined-values-from-array2
I am really surprised to see IE lead the pack here, and to see Chrome behind FF and IE. I don't think I've ever run a test with that result.
Loop backwards. (Removing items will thus not affect the indexes of elements not yet processed.)
If by any chance you're using CoffeeScript then to remove undefined from Array do this
values = ['one', undefined]
values = (item for item in values when item != undefined)
values
/* => ['one'] */
Surprisingly, nobody have answered the best and correct way:
Create new array
Iterate on the old array and only push the elements you want to keep to the new array
some credit goes to #nnnnnn comment
Not gathering exactly what you are trying to achieve, but I feel you are relying on the position index of an item in the array to continue with your program. I would in this case suggest a hashed array, i.e., a Key<>Value pair array.
In which case, arr["2"] always points at the item you had placed in it originally. Thus you can logically/numerically loop through, while not worrying about changes in position.
Beware of the Type Conversion risk and pitfalls!
Your best bet is to create a duplicate of the array, then splice from the original.
Or just go using a collection (key->value) and just delete the key eg
People = {a: "Person A", b: "Person B", c:"Person C"};
delete People.a;
delete People.c; //now the People collection only has 1 entry.
You can replace a,b,c with numbers just using it as an example,
People = {0: "Person A", 1: "Person B", 2:"Person C"};
delete People[0];
delete People[1];
this is a sample for you
<script lanauge = "javascript">
var arr = ["1","2","3","4"];
delete arr[1];// arr[1] is undefined
delete arr[2];// arr[2] is undefined
// now arr.length is 4
var todelete = [];
for (i = 0 ; i < arr.length ;i++)
{
if (typeof arr[i] == 'undefined') todelete.push(i);
}
todelete.sort(function(a, b) { return b-a }); // make the indeies from big to small
for (i = 0;i < todelete.length; i ++)
{
arr.splice(todelete[i],1);
}
// now arr.length is 2
</script>
This may not be what you want, but you can easily calculate what the final element at the end of this procedure will be, then just grab it. Assuming that the elements of the array are contiguous and start at arr[0], you can find:
var logBase2OfLength = Math.floor(Math.log(arr.length) / Math.log(2));
var finalElement = arr[(1 << logBase2OfLength) - 1];
Basically, if you take the integer power of 2 that is less than or equal to the number of elements in your array, that is the position of the element that will remain after all of the looping and deleting.
function removeUndefined(array)
{
var i = 0;
while (i < array.length)
if (typeof array[i] === 'undefined')
array.splice(i, i);
else
i++;
return array;
}
EDIT: I wrote this based on the title. Looks like the question asks something completely different.
>If you are getting undefined during deletion of the key-pair, Then to prevent "undefined" you can try code given below to delete key-pair
1) test = ["1","2","3","4",""," "];
2) var delete = JSON.stringify(test);
case1) delete = delete.replace(/\,""/g,'');
or
case2) delete = delete.replace(/\," "/g,'');
or
case3) delete = delete.replace(/\,null/g,'');
3) var result = JSON.parse(delete);
simply
[NaN, undefined, null, 0, 1, 2, 2000, Infinity].filter(Boolean)
while(yourarray.length>1) //only one left
{
// your code
}

Javascript array sort and unique

I have a JavaScript array like this:
var myData=['237','124','255','124','366','255'];
I need the array elements to be unique and sorted:
myData[0]='124';
myData[1]='237';
myData[2]='255';
myData[3]='366';
Even though the members of array look like integers, they're not integers, since I have already converted each to be string:
var myData[0]=num.toString();
//...and so on.
Is there any way to do all of these tasks in JavaScript?
This is actually very simple. It is much easier to find unique values, if the values are sorted first:
function sort_unique(arr) {
if (arr.length === 0) return arr;
arr = arr.sort(function (a, b) { return a*1 - b*1; });
var ret = [arr[0]];
for (var i = 1; i < arr.length; i++) { //Start loop at 1: arr[0] can never be a duplicate
if (arr[i-1] !== arr[i]) {
ret.push(arr[i]);
}
}
return ret;
}
console.log(sort_unique(['237','124','255','124','366','255']));
//["124", "237", "255", "366"]
You can now achieve the result in just one line of code.
Using new Set to reduce the array to unique set of values.
Apply the sort method after to order the string values.
var myData=['237','124','255','124','366','255']
var uniqueAndSorted = [...new Set(myData)].sort()
UPDATED for newer methods introduced in JavaScript since time of question.
This might be adequate in circumstances where you can't define the function in advance (like in a bookmarklet):
myData.sort().filter(function(el,i,a){return i===a.indexOf(el)})
Here's my (more modern) approach using Array.protoype.reduce():
[2, 1, 2, 3].reduce((a, x) => a.includes(x) ? a : [...a, x], []).sort()
// returns [1, 2, 3]
Edit: More performant version as pointed out in the comments:
arr.sort().filter((x, i, a) => !i || x != a[i-1])
function sort_unique(arr) {
return arr.sort().filter(function(el,i,a) {
return (i==a.indexOf(el));
});
}
How about:
array.sort().filter(function(elem, index, arr) {
return index == arr.length - 1 || arr[index + 1] != elem
})
This is similar to #loostro answer but instead of using indexOf which will reiterate the array for each element to verify that is the first found, it just checks that the next element is different than the current.
Try using an external library like underscore
var f = _.compose(_.uniq, function(array) {
return _.sortBy(array, _.identity);
});
var sortedUnique = f(array);
This relies on _.compose, _.uniq, _.sortBy, _.identity
See live example
What is it doing?
We want a function that takes an array and then returns a sorted array with the non-unique entries removed. This function needs to do two things, sorting and making the array unique.
This is a good job for composition, so we compose the unique & sort function together. _.uniq can just be applied on the array with one argument so it's just passed to _.compose
the _.sortBy function needs a sorting conditional functional. it expects a function that returns a value and the array will be sorted on that value. Since the value that we are ordering it by is the value in the array we can just pass the _.identity function.
We now have a composition of a function that (takes an array and returns a unique array) and a function that (takes an array and returns a sorted array, sorted by their values).
We simply apply the composition on the array and we have our uniquely sorted array.
This function doesn't fail for more than two duplicates values:
function unique(arr) {
var a = [];
var l = arr.length;
for(var i=0; i<l; i++) {
for(var j=i+1; j<l; j++) {
// If a[i] is found later in the array
if (arr[i] === arr[j])
j = ++i;
}
a.push(arr[i]);
}
return a;
};
Here is a simple one liner with O(N), no complicated loops necessary.
> Object.keys(['a', 'b', 'a'].reduce((l, r) => l[r] = l, {})).sort()
[ 'a', 'b' ]
Explanation
Original data set, assume its coming in from an external function
const data = ['a', 'b', 'a']
We want to group all the values onto an object as keys as the method of deduplication. So we use reduce with an object as the default value:
[].reduce(fn, {})
The next step is to create a reduce function which will put the values in the array onto the object. The end result is an object with a unique set of keys.
const reduced = data.reduce((l, r) => l[r] = l, {})
We set l[r] = l because in javascript the value of the assignment expression is returned when an assignment statement is used as an expression. l is the accumulator object and r is the key value. You can also use Object.assign(l, { [r]: (l[r] || 0) + 1 }) or something similar to get the count of each value if that was important to you.
Next we want to get the keys of that object
const keys = Object.keys(reduced)
Then simply use the built-in sort
console.log(keys.sort())
Which is the set of unique values of the original array, sorted
['a', 'b']
The solution in a more elegant way.
var myData=['237','124','255','124','366','255'];
console.log(Array.from(new Set(myData)).sort((a,b) => a - b));
I know the question is very old, but maybe someone will come in handy
A way to use a custom sort function
//func has to return 0 in the case in which they are equal
sort_unique = function(arr,func) {
func = func || function (a, b) {
return a*1 - b*1;
};
arr = arr.sort(func);
var ret = [arr[0]];
for (var i = 1; i < arr.length; i++) {
if (func(arr[i-1],arr[i]) != 0)
ret.push(arr[i]);
}
}
return ret;
}
Example: desc order for an array of objects
MyArray = sort_unique(MyArray , function(a,b){
return b.iterator_internal*1 - a.iterator_internal*1;
});
No redundant "return" array, no ECMA5 built-ins (I'm pretty sure!) and simple to read.
function removeDuplicates(target_array) {
target_array.sort();
var i = 0;
while(i < target_array.length) {
if(target_array[i] === target_array[i+1]) {
target_array.splice(i+1,1);
}
else {
i += 1;
}
}
return target_array;
}
I guess I'll post this answer for some variety. This technique for purging duplicates is something I picked up on for a project in Flash I'm currently working on about a month or so ago.
What you do is make an object and fill it with both a key and a value utilizing each array item. Since duplicate keys are discarded, duplicates are removed.
var nums = [1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10];
var newNums = purgeArray(nums);
function purgeArray(ar)
{
var obj = {};
var temp = [];
for(var i=0;i<ar.length;i++)
{
obj[ar[i]] = ar[i];
}
for (var item in obj)
{
temp.push(obj[item]);
}
return temp;
}
There's already 5 other answers, so I don't see a need to post a sorting function.
// Another way, that does not rearrange the original Array
// and spends a little less time handling duplicates.
function uniqueSort(arr, sortby){
var A1= arr.slice();
A1= typeof sortby== 'function'? A1.sort(sortby): A1.sort();
var last= A1.shift(), next, A2= [last];
while(A1.length){
next= A1.shift();
while(next=== last) next= A1.shift();
if(next!=undefined){
A2[A2.length]= next;
last= next;
}
}
return A2;
}
var myData= ['237','124','255','124','366','255','100','1000'];
uniqueSort(myData,function(a,b){return a-b})
// the ordinary sort() returns the same array as the number sort here,
// but some strings of digits do not sort so nicely numerical.
function sort() only is only good if your number has same digit, example:
var myData = ["3","11","1","2"]
will return;
var myData = ["1","11","2","3"]
and here improvement for function from mrmonkington
myData.sort().sort(function(a,b){return a - b;}).filter(function(el,i,a){if(i==a.indexOf(el) & el.length>0)return 1;return 0;})
the above function will also delete empty array and you can checkout the demo below
http://jsbin.com/ahojip/2/edit
O[N^2] solutions are bad, especially when the data is already sorted, there is no need to do two nested loops for removing duplicates. One loop and comparing to the previous element will work great.
A simple solution with O[] of sort() would suffice. My solution is:
function sortUnique(arr, compareFunction) {
let sorted = arr.sort(compareFunction);
let result = sorted.filter(compareFunction
? function(val, i, a) { return (i == 0 || compareFunction(a[i-1], val) != 0); }
: function(val, i, a) { return (i == 0 || a[i-1] !== val); }
);
return result;
}
BTW, can do something like this to have Array.sortUnique() method:
Array.prototype.sortUnique = function(compareFunction) {return sortUnique(this, compareFunction); }
Furthermore, sort() could be modified to remove second element if compare() function returns 0 (equal elements), though that code can become messy (need to revise loop boundaries in the flight). Besides, I stay away from making my own sort() functions in interpreted languages, since it will most certainly degrade the performance. So this addition is for the ECMA 2019+ consideration.
The fastest and simpleness way to do this task.
const N = Math.pow(8, 8)
let data = Array.from({length: N}, () => Math.floor(Math.random() * N))
let newData = {}
let len = data.length
// the magic
while (len--) {
newData[data[len]] = true
}
var array = [2,5,4,2,5,9,4,2,6,9,0,5,4,7,8];
var unique_array = [...new Set(array)]; // [ 2, 5, 4, 9, 6, 0, 7, 8 ]
var uniqueWithSorted = unique_array.sort();
console.log(uniqueWithSorted);
output = [ 0, 2, 4, 5, 6, 7, 8, 9 ]
Here, we used only Set for removing duplicity from the array and then used sort for sorting array in ascending order.
I'm afraid you can't combine these functions, ie. you gotta do something like this:-
myData.unique().sort();
Alternatively you can implement a kind of sortedset (as available in other languages) - which carries both the notion of sorting and removing duplicates, as you require.
Hope this helps.
References:-
Array.sort
Array.unique

Loop through an array in JavaScript

In Java, you can use a for loop to traverse objects in an array as follows:
String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray) {
// Do something
}
Can I do the same in JavaScript?
Three main options:
for (var i = 0; i < xs.length; i++) { console.log(xs[i]); }
xs.forEach((x, i) => console.log(x));
for (const x of xs) { console.log(x); }
Detailed examples are below.
1. Sequential for loop:
var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
console.log(myStringArray[i]);
//Do something
}
Pros
Works on every environment
You can use break and continue flow control statements
Cons
Too verbose
Imperative
Easy to have off-by-one errors (sometimes also called a fence post error)
2. Array.prototype.forEach:
The ES5 specification introduced a lot of beneficial array methods. One of them, the Array.prototype.forEach, gave us a concise way to iterate over an array:
const array = ["one", "two", "three"]
array.forEach(function (item, index) {
console.log(item, index);
});
Being almost ten years as the time of writing that the ES5 specification was released (Dec. 2009), it has been implemented by nearly all modern engines in the desktop, server, and mobile environments, so it's safe to use them.
And with the ES6 arrow function syntax, it's even more succinct:
array.forEach(item => console.log(item));
Arrow functions are also widely implemented unless you plan to support ancient platforms (e.g., Internet Explorer 11); you are also safe to go.
Pros
Very short and succinct.
Declarative
Cons
Cannot use break / continue
Normally, you can replace the need to break out of imperative loops by filtering the array elements before iterating them, for example:
array.filter(item => item.condition < 10)
.forEach(item => console.log(item))
Keep in mind if you are iterating an array to build another array from it, you should use map. I've seen this anti-pattern so many times.
Anti-pattern:
const numbers = [1,2,3,4,5], doubled = [];
numbers.forEach((n, i) => { doubled[i] = n * 2 });
Proper use case of map:
const numbers = [1,2,3,4,5];
const doubled = numbers.map(n => n * 2);
console.log(doubled);
Also, if you are trying to reduce the array to a value, for example, you want to sum an array of numbers, you should use the reduce method.
Anti-pattern:
const numbers = [1,2,3,4,5];
const sum = 0;
numbers.forEach(num => { sum += num });
Proper use of reduce:
const numbers = [1,2,3,4,5];
const sum = numbers.reduce((total, n) => total + n, 0);
console.log(sum);
3. ES6 for-of statement:
The ES6 standard introduces the concept of iterable objects and defines a new construct for traversing data, the for...of statement.
This statement works for any kind of iterable object and also for generators (any object that has a \[Symbol.iterator\] property).
Array objects are by definition built-in iterables in ES6, so you can use this statement on them:
let colors = ['red', 'green', 'blue'];
for (const color of colors){
console.log(color);
}
Pros
It can iterate over a large variety of objects.
Can use normal flow control statements (break / continue).
Useful to iterate serially asynchronous values.
Cons
If you are targeting older browsers, the transpiled output might surprise you.
Do not use for...in
#zipcodeman suggests the use of the for...in statement, but for iterating arrays for-in should be avoided, that statement is meant to enumerate object properties.
It shouldn't be used for array-like objects because:
The order of iteration is not guaranteed; the array indexes may not be visited in numeric order.
Inherited properties are also enumerated.
The second point is that it can give you a lot of problems, for example, if you extend the Array.prototype object to include a method there, that property will also be enumerated.
For example:
Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];
for (var i in array) {
console.log(array[i]);
}
The above code will console log "a", "b", "c", and "foo!".
That can be particularly a problem if you use some library that relies heavily on native prototypes augmentation (such as MooTools).
The for-in statement, as I said before, is there to enumerate object properties, for example:
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...
console.log("prop: " + prop + " value: " + obj[prop])
}
}
In the above example, the hasOwnProperty method allows you to enumerate only own properties. That's it, only the properties that the object physically has, no inherited properties.
I would recommend you to read the following article:
Enumeration VS Iteration
Yes, assuming your implementation includes the for...of feature introduced in ECMAScript 2015 (the "Harmony" release)... which is a pretty safe assumption these days.
It works like this:
// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
// ... do something with s ...
}
Or better yet, since ECMAScript 2015 also provides block-scoped variables:
// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
// ... do something with s ...
}
// s is no longer defined here
(The variable s is different on each iteration, but can still be declared const inside the loop body as long as it isn't modified there.)
A note on sparse arrays: an array in JavaScript may not actually store as many items as reported by its length; that number is simply one greater than the highest index at which a value is stored. If the array holds fewer elements than indicated by its length, its said to be sparse. For example, it's perfectly legitimate to have an array with items only at indexes 3, 12, and 247; the length of such an array is 248, though it is only actually storing 3 values. If you try to access an item at any other index, the array will appear to have the undefined value there, but the array is nonetheless is distinct from one that actually has undefined values stored. You can see this difference in a number of ways, for example in the way the Node REPL displays arrays:
> a // array with only one item, at index 12
[ <12 empty items>, 1 ]
> a[0] // appears to have undefined at index 0
undefined
> a[0]=undefined // but if we put an actual undefined there
undefined
> a // it now looks like this
[ undefined, <11 empty items>, 1 ]
So when you want to "loop through" an array, you have a question to answer: do you want to loop over the full range indicated by its length and process undefineds for any missing elements, or do you only want to process the elements actually present? There are plenty of applications for both approaches; it just depends on what you're using the array for.
If you iterate over an array with for..of, the body of the loop is executed length times, and the loop control variable is set to undefined for any items not actually present in the array. Depending on the details of your "do something with" code, that behavior may be what you want, but if not, you should use a different approach.
Of course, some developers have no choice but to use a different approach anyway, because for whatever reason they're targeting a version of JavaScript that doesn't yet support for...of.
As long as your JavaScript implementation is compliant with the previous edition of the ECMAScript specification (which rules out, for example, versions of Internet Explorer before 9), then you can use the Array#forEach iterator method instead of a loop. In that case, you pass a function to be called on each item in the array:
var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) {
// ... do something with s ...
} );
You can of course use an arrow function if your implementation supports ES6+:
myStringArray.forEach( s => {
// ... do something with s ...
} );
Unlike for...of, .forEach only calls the function for elements that are actually present in the array. If passed our hypothetical array with three elements and a length of 248, it will only call the function three times, not 248 times. If this is how you want to handle sparse arrays, .forEach may be the way to go even if your interpreter supports for...of.
The final option, which works in all versions of JavaScript, is an explicit counting loop. You simply count from 0 up to one less than the length and use the counter as an index. The basic loop looks like this:
var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
s = myStringArray[i];
// ... do something with s ...
}
One advantage of this approach is that you can choose how to handle sparse arrays. The above code will run the body of the loop the full length times, with s set to undefined for any missing elements, just like for..of; if you instead want to handle only the actually-present elements of a sparse array, like .forEach, you can add a simple in test on the index:
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 ...
}
}
Depending on your implementation's optimizations, assigning the length value to the local variable (as opposed to including the full myStringArray.length expression in the loop condition) can make a significant difference in performance since it skips a property lookup each time through. You may see the length caching done in the loop initialization clause, like this:
var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {
The explicit counting loop also means you have access to the index of each value, should you want it. The index is also passed as an extra parameter to the function you pass to forEach, so you can access it that way as well:
myStringArray.forEach( (s,i) => {
// ... do something with s and i ...
});
for...of doesn't give you the index associated with each object, but as long as the object you're iterating over is actually an instance of Array (and not one of the other iterable types for..of works on), you can use the Array#entries method to change it to an array of [index, item] pairs, and then iterate over that:
for (const [i, s] of myStringArray.entries()) {
// ... do something with s and i ...
}
The for...in syntax mentioned by others is for looping over an object's properties; since an Array in JavaScript is just an object with numeric property names (and an automatically-updated length property), you can theoretically loop over an Array with it. But the problem is that it doesn't restrict itself to the numeric property values (remember that even methods are actually just properties whose value is a closure), nor is it guaranteed to iterate over those in numeric order. Therefore, the for...in syntax should not be used for looping through Arrays.
You can use map, which is a functional programming technique that's also available in other languages like Python and Haskell.
[1,2,3,4].map( function(item) {
alert(item);
})
The general syntax is:
array.map(func)
In general func would take one parameter, which is an item of the array. But in the case of JavaScript, it can take a second parameter which is the item's index, and a third parameter which is the array itself.
The return value of array.map is another array, so you can use it like this:
var x = [1,2,3,4].map( function(item) {return item * 10;});
And now x is [10,20,30,40].
You don't have to write the function inline. It could be a separate function.
var item_processor = function(item) {
// Do something complicated to an item
}
new_list = my_list.map(item_processor);
which would be sort-of equivalent to:
for (item in my_list) {item_processor(item);}
Except you don't get the new_list.
for (const s of myStringArray) {
(Directly answering your question: now you can!)
Most other answers are right, but they do not mention (as of this writing) that ECMAScript  6  2015 is bringing a new mechanism for doing iteration, the for..of loop.
This new syntax is the most elegant way to iterate an array in JavaScript (as long you don't need the iteration index).
It currently works with Firefox 13+, Chrome 37+ and it does not natively work with other browsers (see browser compatibility below). Luckily we have JavaScript compilers (such as Babel) that allow us to use next-generation features today.
It also works on Node.js (I tested it on version 0.12.0).
Iterating an array
// You could also use "let" or "const" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) {
console.log(letter);
}
Iterating an array of objects
const band = [
{firstName : 'John', lastName: 'Lennon'},
{firstName : 'Paul', lastName: 'McCartney'}
];
for(const member of band){
console.log(member.firstName + ' ' + member.lastName);
}
Iterating a generator:
(example extracted from 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 (const n of fibonacci()) {
console.log(n);
// Truncate the sequence at 1000
if (n >= 1000) {
break;
}
}
Compatibility table:
http://kangax.github.io/compat-table/es6/#test-for..of_loops
Specification: http://wiki.ecmascript.org/doku.php?id=harmony:iterators
}
In JavaScript it's not advisable to loop through an Array with a for-in loop, but it's better to use a for loop such as:
for(var i=0, len=myArray.length; i < len; i++){}
It's optimized as well ("caching" the array length). If you'd like to learn more, read my post on the subject.
6 different methods to loop through the array
You can loop through an array by many different methods. I have sorted my 6 favorite methods from top to bottom.
1. Using for loop
When it's to simply loop through an array, the for loop is my first choice.
let array = [1, 2, 3, 4, 5];
for (let i = 0; i < array.length; i++) {
console.log(array[i]);
}
2. Using forEach loop
forEach loop is a modern way to loop through the array. Also, it gives more flexibility and control over the array and elements.
let array = [1, 2, 3, 4, 5];
array.forEach((element) => {
console.log(element);
});
3. Using for...of
for...of loop gives you direct access to the array elements.
let array = [1, 2, 3, 4, 5];
for (let element of array) {
console.log(element);
}
4. Using for...in loop
for...in gives you a key using which you can access array elements.
let array = [1, 2, 3, 4, 5];
for(let index in array){
console.log(array[index]);
}
5. Using while loop
while loop is can be used to loop through the array as well.
let array = [1, 2, 3, 4, 5];
let length = array.length;
while(length > 0){
console.log(array[array.length - length]);
length--;
}
6. Using do...while loop
Likewise, I use do...while loop
let array = [1, 2, 3, 4, 5];
let length = array.length;
do {
console.log(array[array.length - length]);
length--;
}
while (length > 0)
Opera, Safari, Firefox and Chrome now all share a set of enhanced Array methods for optimizing many common loops.
You may not need all of them, but they can be very useful, or would be if every browser supported them.
Mozilla Labs published the algorithms they and WebKit both use, so that you can add them yourself.
filter returns an array of items that satisfy some condition or test.
every returns true if every array member passes the test.
some returns true if any pass the test.
forEach runs a function on each array member and doesn't return anything.
map is like forEach, but it returns an array of the results of the operation for each element.
These methods all take a function for their first argument and have an optional second argument, which is an object whose scope you want to impose on the array members as they loop through the function.
Ignore it until you need it.
indexOf and lastIndexOf find the appropriate position of the first or last element that matches its argument exactly.
(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;
})();
Introduction
Since my time in college, I've programmed in Java, JavaScript, Pascal, ABAP, PHP, Progress 4GL, C/C++ and possibly a few other languages I can't think of right now.
While they all have their own linguistic idiosyncrasies, each of these languages share many of the same basic concepts. Such concepts include procedures / functions, IF-statements, FOR-loops, and WHILE-loops.
A traditional for-loop
A traditional for loop has three components:
The initialization: executed before the look block is executed the first time
The condition: checks a condition every time before the loop block is executed, and quits the loop if false
The afterthought: performed every time after the loop block is executed
These three components are separated from each other by a ; symbol. Content for each of these three components is optional, which means that the following is the most minimal for loop possible:
for (;;) {
// Do stuff
}
Of course, you will need to include an if(condition === true) { break; } or an if(condition === true) { return; } somewhere inside that for-loop to get it to stop running.
Usually, though, the initialization is used to declare an index, the condition is used to compare that index with a minimum or maximum value, and the afterthought is used to increment the index:
for (var i = 0, length = 10; i < length; i++) {
console.log(i);
}
Using a traditional for loop to loop through an array
The traditional way to loop through an array, is this:
for (var i = 0, length = myArray.length; i < length; i++) {
console.log(myArray[i]);
}
Or, if you prefer to loop backwards, you do this:
for (var i = myArray.length - 1; i > -1; i--) {
console.log(myArray[i]);
}
There are, however, many variations possible, like for example this one:
for (var key = 0, value = myArray[key], length = myArray.length; key < length; value = myArray[++key]) {
console.log(value);
}
...or this one...
var i = 0, length = myArray.length;
for (; i < length;) {
console.log(myArray[i]);
i++;
}
...or this one:
var key = 0, value;
for (; value = myArray[key++];){
console.log(value);
}
Whichever works best is largely a matter of both personal taste and the specific use case you're implementing.
Note that each of these variations is supported by all browsers, including very very old ones!
A while loop
One alternative to a for loop is a while loop. To loop through an array, you could do this:
var key = 0;
while(value = myArray[key++]){
console.log(value);
}
Like traditional for loops, while loops are supported by even the oldest of browsers.
Also, note that every while loop can be rewritten as a for loop. For example, the while loop hereabove behaves the exact same way as this for-loop:
for(var key = 0; value = myArray[key++];){
console.log(value);
}
For...in and for...of
In JavaScript, you can also do this:
for (i in myArray) {
console.log(myArray[i]);
}
This should be used with care, however, as it doesn't behave the same as a traditional for loop in all cases, and there are potential side-effects that need to be considered. See Why is using "for...in" for array iteration a bad idea? for more details.
As an alternative to for...in, there's now also for for...of. The following example shows the difference between a for...of loop and a for...in loop:
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
}
Additionally, you need to consider that no version of Internet Explorer supports for...of (Edge 12+ does) and that for...in requires at least Internet Explorer 10.
Array.prototype.forEach()
An alternative to for-loops is Array.prototype.forEach(), which uses the following syntax:
myArray.forEach(function(value, key, myArray) {
console.log(value);
});
Array.prototype.forEach() is supported by all modern browsers, as well as Internet Explorer 9 and later.
Libraries
Finally, many utility libraries also have their own foreach variation. AFAIK, the three most popular ones are these:
jQuery.each(), in jQuery:
$.each(myArray, function(key, value) {
console.log(value);
});
_.each(), in Underscore.js:
_.each(myArray, function(value, key, myArray) {
console.log(value);
});
_.forEach(), in Lodash:
_.forEach(myArray, function(value, key) {
console.log(value);
});
Use the while loop...
var i = 0, item, items = ['one', 'two', 'three'];
while(item = items[i++]){
console.log(item);
}
It logs: 'one', 'two', and 'three'
And for the reverse order, an even more efficient loop:
var items = ['one', 'two', 'three'], i = items.length;
while(i--){
console.log(items[i]);
}
It logs: 'three', 'two', and 'one'
Or the classical for loop:
var items = ['one', 'two', 'three']
for(var i=0, l = items.length; i < l; i++){
console.log(items[i]);
}
It logs: 'one','two','three'
Reference: Google Closure: How not to write JavaScript
If you want a terse way to write a fast loop and you can iterate in reverse:
for (var i=myArray.length;i--;){
var item=myArray[i];
}
This has the benefit of caching the length (similar to for (var i=0, len=myArray.length; i<len; ++i) and unlike for (var i=0; i<myArray.length; ++i)) while being fewer characters to type.
There are even some times when you ought to iterate in reverse, such as when iterating over a live NodeList where you plan on removing items from the DOM during iteration.
Some use cases of looping through an array in the functional programming way in JavaScript:
1. Just loop through an array
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
});
Note: Array.prototype.forEach() is not a functional way strictly speaking, as the function it takes as the input parameter is not supposed to return a value, which thus cannot be regarded as a pure function.
2. Check if any of the elements in an array pass a test
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. Transform to a new array
const myArray = [{x:100}, {x:200}, {x:300}];
const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]
Note: The map() method creates a new array with the results of calling a provided function on every element in the calling array.
4. Sum up a particular property, and calculate its average
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. Create a new array based on the original but without modifying it
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. Count the number of each category
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. Retrieve a subset of an array based on particular criteria
const myArray = [{x:100}, {x:200}, {x:300}];
const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}]
Note: The filter() method creates a new array with all elements that pass the test implemented by the provided function.
8. Sort an array
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. Find an element in an array
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);
The Array.prototype.find() method returns the value of the first element in the array that satisfies the provided testing function.
References
Array.prototype.some()
Array.prototype.forEach()
Array.prototype.map()
Array.prototype.filter()
Array.prototype.sort()
Spread syntax
Array.prototype.find()
Yes, you can do the same in JavaScript using a loop, but not limited to that. There are many ways to do a loop over arrays in JavaScript. Imagine you have this array below, and you'd like to do a loop over it:
var arr = [1, 2, 3, 4, 5];
These are the solutions:
1) For loop
A for loop is a common way looping through arrays in JavaScript, but it is no considered as the fastest solutions for large arrays:
for (var i=0, l=arr.length; i<l; i++) {
console.log(arr[i]);
}
2) While loop
A while loop is considered as the fastest way to loop through long arrays, but it is usually less used in the JavaScript code:
let i=0;
while (arr.length>i) {
console.log(arr[i]);
i++;
}
3) Do while
A do while is doing the same thing as while with some syntax difference as below:
let i=0;
do {
console.log(arr[i]);
i++;
}
while (arr.length>i);
These are the main ways to do JavaScript loops, but there are a few more ways to do that.
Also we use a for in loop for looping over objects in JavaScript.
Also look at the map(), filter(), reduce(), etc. functions on an Array in JavaScript. They may do things much faster and better than using while and for.
This is a good article if you like to learn more about the asynchronous functions over arrays in JavaScript.
Functional programming has been making quite a splash in the
development world these days. And for good reason: Functional
techniques can help you write more declarative code that is easier to
understand at a glance, refactor, and test.
One of the cornerstones of functional programming is its special use
of lists and list operations. And those things are exactly what the
sound like they are: arrays of things, and the stuff you do to them.
But the functional mindset treats them a bit differently than you
might expect.
This article will take a close look at what I like to call the "big
three" list operations: map, filter, and reduce. Wrapping your head
around these three functions is an important step towards being able
to write clean functional code, and opens the doors to the vastly
powerful techniques of functional and reactive programming.
It also means you'll never have to write a for loop again.
Read more>> here:
There is a way to do it where you have very little implicit scope in your loop and do away with extra variables.
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.
}
Or if you really want to get the id and have a really classical for loop:
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
}
Modern browsers all support iterator methods forEach, map, reduce, filter and a host of other methods on the Array prototype.
There are various way to loop through array in JavaScript.
Generic loop:
var i;
for (i = 0; i < substr.length; ++i) {
// Do something with `substr[i]`
}
ES5's 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)
});
Have a look this for detailed information or you can also check MDN for looping through an array in JavaScript & using jQuery check jQuery for each.
Array loop:
for(var i = 0; i < things.length; i++){
var thing = things[i];
console.log(thing);
}
Object loop:
for(var prop in obj){
var propValue = obj[prop];
console.log(propValue);
}
I would thoroughly recommend making use of the Underscore.js library. It provides you with various functions that you can use to iterate over arrays/collections.
For instance:
_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...
If anybody is interested in the performance side of the multiple mechanisms available for Array iterations, I've prepared the following JSPerf tests:
https://jsperf.com/fastest-array-iterator
Results:
The traditional for() iterator, is by far the fastest method, especially when used with the array length cached.
let arr = [1,2,3,4,5];
for(let i=0, size=arr.length; i<size; i++){
// Do something
}
The Array.prototype.forEach() and the Array.prototype.map() methods are the slowest approximations, probably as a consequence of the function call overhead.
I did not yet see this variation, which I personally like the best:
Given an array:
var someArray = ["some", "example", "array"];
You can loop over it without ever accessing the length property:
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);
}
See this JsFiddle demonstrating that: http://jsfiddle.net/prvzk/
This only works for arrays that are not sparse. Meaning that there actually is a value at each index in the array. However, I found that in practice I hardly ever use sparse arrays in JavaScript... In such cases it's usually a lot easier to use an object as a map/hashtable. If you do have a sparse array, and want to loop over 0 .. length-1, you need the for (var i=0; i<someArray.length; ++i) construct, but you still need an if inside the loop to check whether the element at the current index is actually defined.
Also, as CMS mentions in a comment below, you can only use this on arrays that don't contain any falsish values. The array of strings from the example works, but if you have empty strings, or numbers that are 0 or NaN, etc. the loop will break off prematurely. Again in practice this is hardly ever a problem for me, but it is something to keep in mind, which makes this a loop to think about before you use it... That may disqualify it for some people :)
What I like about this loop is:
It's short to write
No need to access (let alone cache) the length property
The item to access is automatically defined within the loop
body under the name you pick.
Combines very naturally with array.push and array.splice to use arrays like lists/stacks
The reason this works is that the array specification mandates that when you read an item from an index >= the array's length, it will return undefined. When you write to such a location it will actually update the length.
For me, this construct most closely emulates the Java 5 syntax that I love:
for (String item : someArray) {
}
... with the added benefit of also knowing about the current index inside the loop
If you're using the jQuery library, consider using
http://api.jquery.com/jQuery.each/
From the documentation:
jQuery.each( collection, callback(indexInArray, valueOfElement) )
Returns: Object
Description: A generic iterator function, which can be used to
seamlessly iterate over both objects and arrays. Arrays and array-like
objects with a length property (such as a function's arguments object)
are iterated by numeric index, from 0 to length-1. Other objects are
iterated via their named properties.
The $.each() function is not the same as $(selector).each(), which is
used to iterate, exclusively, over a jQuery object. The $.each()
function can be used to iterate over any collection, whether it is a
map (JavaScript object) or an array. In the case of an array, the
callback is passed an array index and a corresponding array value each
time. (The value can also be accessed through the this keyword, but
Javascript will always wrap the this value as an Object even if it is
a simple string or number value.) The method returns its first
argument, the object that was iterated.
There are 4 ways of array iteration:
// 1: for
for (let i = 0; i < arr.length; ++i) {
console.log(arr[i]);
}
// 2: forEach
arr.forEach((v, i) => console.log(v));
// 3: for in
for (let i in arr) {
console.log(arr[i]);
}
// 4: for of
for (const v of arr) {
console.log(v);
}
Summary: 1 and 3 solutions create extra variable, 2 - create extra function context. The best way is 4th - "for of".
Esoteric
let a= ["Hello", "World"];
while(a.length) { console.log( a.shift() ); }
Performance test
Today (2022-11-13) I perform a test on Chrome 107, Safari 15.2 and Firefox 106 on chosen solutions.
Conclusions
solutions C and D are fast or fastest on all browsers for all arrays.
solution A and B are slowest on all browsers for all arrays
Results
Details
I perform 3 tests:
small - for 2 elements array (like OP) - you can run it here
medium - for 10K elements array and - you can run it here
big - for 100K elements array - you can run it here
The below snippet presents code used in the test.
function A(a) {
let r=0;
while(a.length) r+= a.shift().length;
return r;
}
function B(a) {
let r=0;
for(i in a) r+= a[i].length;
return r;
}
function C(a) {
let r=0;
for(x of a) r+= x.length;
return r;
}
function D(a) {
let r=0;
for (i=0; i<a.length; ++i) r+= a[i].length;
return r;
}
function E(a) {
let r=0;
a.forEach(x=> r+= x.length);
return r;
}
let arr= ["Hello", "World!"];
[A,B,C,D,E].forEach(f => console.log(`${f.name}: ${f([...arr])}`))
Here are example results for Chrome for a medium array:
There's a method to iterate over only own object properties, not including prototype's ones:
for (var i in array) if (array.hasOwnProperty(i)) {
// Do something with array[i]
}
but it still will iterate over custom-defined properties.
In JavaScript any custom property could be assigned to any object, including an array.
If one wants to iterate over sparsed array, for (var i = 0; i < array.length; i++) if (i in array) or array.forEach with es5shim should be used.
The most elegant and fast way
var arr = [1, 2, 3, 1023, 1024];
for (var value; value = arr.pop();) {
value + 1
}
http://jsperf.com/native-loop-performance/8
Edited (because I was wrong)
Comparing methods for looping through an array of 100000 items and do a minimal operation with the new value each time.
http://jsben.ch/#/BQhED
Preparation:
<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>
Tests:
<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>
There are a couple of ways to do it in JavaScript. The first two examples are JavaScript samples. The third one makes use of a JavaScript library, that is, jQuery making use of the .each() function.
var myStringArray = ["hello", "World"];
for(var i in myStringArray) {
alert(myStringArray[i]);
}
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>
The optimized approach is to cache the length of array and using the single variable pattern, initializing all variables with a single var keyword.
var i, max, myStringArray = ["Hello", "World"];
for (i = 0, max = myStringArray.length; i < max; i++) {
alert(myStringArray[i]);
// Do something
}
If the order of iteration does not matter then you should try reversed loop. It is the fastest as it reduces overhead condition testing and decrement is in one statement:
var i,myStringArray = ["item1","item2"];
for (i = myStringArray.length; i--) {
alert(myStringArray[i]);
}
Or better and cleaner to use a while loop:
var myStringArray = ["item1","item2"],i = myStringArray.length;
while(i--) {
// Do something with fruits[i]
}
In JavaScript, there are so many solutions to loop an array.
The code below are popular ones
/** 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()
If you want to use jQuery, it has a nice example in its documentation:
$.each([ 52, 97 ], function( index, value ) {
alert( index + ": " + value );
});
The best way in my opinion is to use the Array.forEach function. If you cannot use that I would suggest to get the polyfill from MDN. To make it available, it is certainly the safest way to iterate over an array in JavaScript.
Array.prototype.forEach()
So as others has suggested, this is almost always what you want:
var numbers = [1,11,22,33,44,55,66,77,88,99,111];
var sum = 0;
numbers.forEach(function(n){
sum += n;
});
This ensures that anything you need in the scope of processing the array stays within that scope, and that you are only processing the values of the array, not the object properties and other members, which is what for .. in does.
Using a regular C-style for loop works in most cases. It is just important to remember that everything within the loop shares its scope with the rest of your program, the { } does not create a new scope.
Hence:
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);
will output "11" - which may or may not be what you want.
A working jsFiddle example:
https://jsfiddle.net/workingClassHacker/pxpv2dh5/7/
It's not 100% identical, but similar:
var myStringArray = ['Hello', 'World']; // The array uses [] not {}
for (var i in myStringArray) {
console.log(i + ' -> ' + myStringArray[i]); // i is the index/key, not the item
}
For example, I used in a Firefox console:
[].forEach.call(document.getElementsByTagName('pre'), function(e){
console.log(e);
})
You can use querySelectorAll to get same result
document.querySelectorAll('pre').forEach( (e) => {
console.log(e.textContent);
})
<pre>text 1</pre>
<pre>text 2</pre>
<pre>text 3</pre>

Categories

Resources