I can either do,
var arr = [];
arr.forEach(function(i) {
i;
});
for (var i = 0, length = arr.length; i < length; ++i) {
arr[i];
}
When should I use one over the other, is there performance differences?
You use foreach whenever :
your array is associtive or has gaps, i.e. you cannot reach every element by an incremented number (1,2,5, 'x', -7)
you need to iterate in exactly the same order as they appear in the array. (e.g. 2,1,3)
you want to be sure not the get into an endless loop
The last point is the main difference: foreach works on a copy, so even if you alter the elements, the array remains intact and can be iterated without defects.
That copy makes foreach somewhat slower than for, since it has to copy data. Keep in mind that some old or rare browsers don´t supports foreach, but they do support "for". Unless your array is really big (10.000 + items), ignore the speed difference. It´s in the milliseconds.
You use for whenever
you want an easy way to aler the array you are moving on
you want specific sequences, e.g. for ($i=100; $i < 1000; $i += 5) resulting in 100, 105, 110...
Related
I am basically trying to sort an input of numbers on the fly by inserting the numbers to the correct position (not 100% sure but this should be insertion sort). My understanding is that to insert into an array in javascript you need to use the array splice method http://www.w3schools.com/jsref/jsref_splice.asp .
My code in attempt of achieving my goal is as below:
var N = parseInt(readline());
var powers = [0];
for (var i = 0; i < N; i++) {
var pi = parseInt(readline());
for(var j=i;j<powers.length; j++ ){
if(powers[j]>pi){
powers.splice(j,0,pi);
}
else if(j+1==powers.length){
powers[j+1]=pi;
}
}
}
When I run this code I get an out of memory exception. I just want to understand is what I am doing wrong in the code above. If I am using the splice method wrong and it is the cause of the memory leak, what is actually happening under the hood?
I know there are other ways I could do this sorting but I am particularly interested in doing an insertion sort with javascript arrays.
In your else condition, you're adding to the array, making it one longer. That means when the loop next checks powers.length, it will be a higher number, which means you'll go into the loop body again, which means you'll add to the array again, which means you'll go back into the loop body again, which means...you see where this is going. :-)
Once you've added the number to the array (regardless of which branch), exit the loop (for instance, with break).
Side note: You won't be doing a proper insertion sort if you start j at i as you are currently. i is just counting how many entries the user said they were going to enter, it's not part of the sort. Consider: What if I enter 8 and then 4? If you start j at i, you'll skip over 8 and put 4 in the wrong place. j needs to start at 0.
I've got two arrays, numbers and picks. numbers contains a series of numbers, and picks is currently empty. I want to pull N values out of numbers, and put them in picks. So I've tried picks.push(numbers.splice(idx,1));, where idx is a random number between 0 and the highest index in numbers. This doesn't seem to be working. Any advice would be appreciated.
Since splice returns an array, you only need a small tweak, to retrieve the first (and only) item in this new array:
picks.push(numbers.splice(idx,1)[0]);
Well, as many others said, Array.splice() returns an array (with the elements ordered to remove from the source array). So you can either use the fact that you always take a single number from it, as in #JoeEnos answer, or employ more universal form:
[].push.apply(picks, number.splice(idx, 1));
// replace 1 with any other positive number, and it still works
Still, it looks to me you're just trying to reimplement Fisher-Yates shuffle algorithm. Here, the key is using not splice (as reordering huge arrays might cause a performance hit), but exchange the chosen element with the one at the end of the source array. Here's how it can be done:
var source = [1,2,3,4,5,6,7,8];
var shuffled = Array(source.length);
var i, j, len;
for (i = 0, len = shuffled.length; i < len; ++i) {
j = Math.random() * (i + 1)|0;
if (i !== j) {
shuffled[i] = shuffled[j];
}
shuffled[j] = source[i];
}
console.log(shuffled);
Here's eval.in demo to play with.
I know the classic way of looping through an array arr is:
for(var i=0 ; i<arr.length ; i++) {
// code
}
But someone recently showed me a different way of implementing the condition inside that loop, like this:
for(var i=0 ; arr[i] !== undefined ; i++) {
I think this solution is interesting because this is exactly what you need when you loop through an array: you don't want to get undefineds when you try to access an undefined index.
I realize that if you count the characters it looks longer, and also that you might have some problems with arrays like this: ["Hello", , "World"], but apart from that - is there anything else I'm missing here? Why shouldn't we be using this technique instead?
Why shouldn't we be using this technique instead?
It doesn't work on sparse arrays (as you mentioned)
It doesn't work on arrays that contain undefined values
It's not as easily optimised (assuming the .length stays constant during the loop)
(In the old days, the undefined identifier could be overwritten, you'd need to use typeof)
Of cource, wheter it "works" for you depends on the use case, and sometimes you might want to use it. Most times, you simply don't.
And even if both ways would work in your case, it's better practise to use the standard approach (i<arr.length) as there is lower mental overhead. Everyone recognises that pattern and knows what it does, while with arr[i]!==undefined one would need to think about why the uncommon approach was chosen.
Sometimes arrays have empty values and your way of iteration will fail.
var arr = [];
arr[5] = 5;
for (var i = 0; arr[i] !== undefined; ++i) {
console.log(arr[i]);
}
console.log('done');
If you want to iterate real array values and skip undefined's, i suggest you to filter the array first and do iteration after. So your code will be more understandable. Example:
var arr = [];
arr[5] = 5;
arr.filter(Boolean).forEach(function (e) {
console.log(e);
});
console.log('done');
Are there any performance difference between
var a = [10,20,30,40];// Assume we have thousands of values here
// Approach 1
var i, len = a.length;
for(i=0;i<len;i++){
alert(i);
alert(a[i]);
}
// Approach 2
for( i in a ){
alert(i);
alert(a[i]);
}
Use for (var i = 0, len = a.length; i < len; i++) because it's way faster and it's the correct way or iterating the items in an array.
First: It's not correct to iterate arrays with for (i in a) because that iteration will include enumerable properties in addition to array elements. If any methods or properties have been added to the array, they will be part of the iteration when using for (i in a) which is never what you want when trying to traverse the elements of the array.
Second: The correct option is a lot faster (9-20x faster). See this jsPerf test which shows the for (var i = 0; i < len; i++) option to be about 9x faster in Chrome and even more of a speed difference in Firefox: http://jsperf.com/for-loop-comparison2.
As an example of the problems that can occur when using for (var i in a), when I use that when the mootools library is included in the project, I get all these values for i:
0
1
2
3
$family
$constructor
each
clone
clean
invoke
associate
link
contains
append
getLast
getRandom
include
combine
erase
empty
flatten
pick
hexToRgb
rgbToHex
which appears to be a bunch of methods that mootools has added to the array object.
I don't know across browsers, but in my test with Firefox there is. for (i=0; etc...) is much faster. Here is a jsfiddle example that shows the difference. http://jsfiddle.net/pseudosavant/VyRH3/
Add to that the problems that you can encounter with (for i in etc) when the Array object has been prototype (perhaps in a library), you should always use for (i=0; etc...) for looping over arrays.
(for i in etc) should only ever be used on objects.
for (var ctr = arr.length - 1; ctr >= 0; ctr--) {
}
for (var ctr = 0; ctr < arr.length; ctr++) {
}
Does both of them does the same job or the first one does things
differently.
Which is the best way to perform compared to the above
two.
First one will start from bottom of array and will reach top. Second one will start from top to bottom of array.
If your array has { 3, 2, 1 } and you print this in first loop, it will print 1, 2, 3 and in second loop it will print 3, 2, 1.
Found this http://oreilly.com/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html which tells about improving performance of javascript. According to it
Another simple way to improve the performance of a loop is to decrement the iterator toward 0 rather than incrementing toward the total length. Making this simple change can result in savings of up to 50% off the original execution time, depending on the complexity of each iteration.
So first one will give better performance.
Hope this helps you.
The first one loops through the array in reverse. The second one in the order the elements appear.
The two loops are different in the direction of an array traversal:
starts from the last element and finishes in the first element
vice versa, starts from the fist element and finishes in the last one
Which is the best, depends on your needs.
Consider, for example, the task of finding the first/last occurrence of a character in an array.
They both iterate over the contents of an array, but they do it in opposite directions. The first starts from the last element of the array, and works backwards to the first element; the second starts from the first element, and works forwards to the last.
In most cases, they'll provide the same results. However, it's a common practice when you're going to be removing elements from an array to iterate backwards (the first code sample), as any changes to the indices after removing an element will only affect the elements that have already been examined.
The first loops backwards. The second loops forwards.
The first will have better performance (because the second has to access the arr.length each time it goes around the loop), but not significantly so unless you are dealing with a lot of objects or looping over them many times.
You can get a similar performance boost with:
for (var i = 0, j = arr.length; i < j; i++) {
}