I am now practicing some methods in javascript, like shift(), unshift(), push(), pop(), and I want to write a little function that will take 3 arguments, an array, a start point, an end point. Which is used to cut a part of array out, and then return both the new array and the cut part. Not a useful thing or a big deal, just want to practice javascript.
But I encountered a strange thing, which I don't know why.
Here is the strange part
var a1 = [];
var a2 = [9,8,7,6,5,4,3,2,1];
for(var i=0; i<a2.length; i++){
a1.unshift(a2.shift())
}
So I wrote this code, and the expected result should be
a1 = [1,2,4,5,6,7,8,9]
a2 = []
However, when I run the code, this was what actually happened
a1 = [5,6,7,8,9]
a2 = [4,3,2,1]
It seems like the function was looped not enough time, so I tried to change the a2.length to a integer: 9
which make the code become
var a1 = [];
var a2 = [9,8,7,6,5,4,3,2,1];
for(var i=0; i<9; i++){
a1.unshift(a2.shift())
}
And that worked!
Then I change the approach to this
var a1 = [];
var a2 = [9,8,7,6,5,4,3,2,1]
var aLength = a2.length;
for(var i=0; i<aLength; i++){
a1.unshift(a2.shift())
}
And this worked too!!!
Could anyone tell me why is that ???
And how can I improve the loop?
Thank you very much, really appreciate for your time.
You could easily do this by using while loop
while (a2.length > 0)
{
a1.unshift(a2.shift());
}
The loop condition is re-evaluated for each iteration, and a2.length is constantly changing.
If you want to use its initial value, cache it beforehand:
var n = a2.length;
for (var i = 0; i < n; i++) {
a1.unshift(a2.shift());
}
Javascript Array: Shift() Method
The shift() method is like the pop() method, only it works at the
beginning of the array. The shift() method pulls the first element off
of the given array and returns it. This alters the array on which the
method was called.
So when you do a a2.shift() it will actually modify (decrease the number of elements in the array) the array and thus the effect
Related
I am trying to understand for loops totally. I made my research and understand a little.
I Know loops like
for(var i = 0; i < 5; i++) { console.log(i) }
Which means continue to increment i starting from 0 as log as i is less than 5
I also know loops like
var a = [];
a[5] = 5;
for (var x in a) {
console.log(x);
}
Which means loop for x in a and would log 5;
Was searching playing around researching and then i see something like
function aNumber() {
var aInt = 521;
var intString = aInt.toString();
var intLength = intString.length;
var result = 0;
for (var i in intString) {
result += Math.pow((+intString[i]), intLength);
}
console.log(result);
//...
}
aNumber();
I understand the conversion of int to string. But the loop is new to me.
I know what the Math.pow() function does like it take to parameters (Math.pow(2,2) is same as 2**2) and the + in +intString passes the string as an int What i don't really understand is this part here
result += Math.pow((+intString[i]), intLength);
Its making the whole loop look confusing.
Can someone help explain it for me in simple terms just like i explained the others? Thanks
for..in loops iterate over the enumerable property names on the object (including properties inherited from the prototype). Because strings' enumerable properties are always their numeric indicies and nothing else, the line:
for (var i in intString)
can be replaced with
for (let i = 0; i < intString.length; i++)
while leaving the rest of the code the same, and it will perform identically. The intString[i] expression just refers to the current character being iterated over.
But I wouldn't recommend using for..in loops in most cases - it's not hard to confuse with for..of (which is quite different), and array methods are often nicer to work with. For example, the code that generates the result in your code can be replaced with the use of Array.prototype.reduce, which can generate the result at once, without any reassignment:
const intString = '521';
const intLength = intString.length;
const result = Array.prototype.reduce.call(
intString,
(a, intChar) => a + (intChar ** intLength),
0 // initial value of accumulator a
);
console.log(result);
I have an array of objects
x = [{id:null},{id:null},{id:null},{id:null}];
Lets say that the values for the array changed
x = [{id:1},{id:3},{id:8},{id:12}];
And i wanted to revert the values to all null,which method will be faster for performance
A) Reconstructing the array again
x=[];
for (var i=0; i<5; i++) {
var obj = {};
obj.id = null;
x.push(obj);
}
B) Resetting the values
for (var i in x) {
x.id = null;
}
Unless you have thousands of elements, you will never notice a difference in performances.
However the second solution is more clear than the first one.
Alternatively, to make it clear x is an array:
for (var i = 0; i < x.length; ++i) {
x[i].id = null;
}
Your B will just add property id to your array and set it's value to 'null'. On top of that, you should not use for in on arrays.
Fastest way would probably be:
var i = x.length;
while(i--){
x[i].id = null;
}
But you wouldn't see the difference unless your array has thousands of elements, and probably shouldn't even try to optimize it for the performance, before you're sure that you need to. In most use cases readability of the code will be much more important than a few fragments of a second that you could gain.
If I have the following:
var a = 5;
How can I make it so that this is converted into
[0,1,2,3,4]
I know it's a very simple question but I have never seen it done and cannot think of a simple way of doing it.
You can just use a loop and do:
var a = 5;
var arr = [];
for(var i=0; i<a; i++) {
arr.push(i);
}
As others have stated in their answers,
Array direct assignment is even faster than Push
Having used jsperf, that appears to be incorrect for Chrome/Firefox. See below:
http://jsperf.com/js-array232
From this, I would use push as stated in my answer above.
Array direct assignment is even faster than Push :
var arr=[],n=5;//N is 5 in your case
while(n--)
{
arr[n]=n;
};
Performance proof for Internet Explorer:
http://jsperf.com/js-array232/4
The easy, obvious solution is just to use a for loop,
var a = 5, arr = [];
for (var i=0;i<a;arr.push(i++));
arr now contains your ascending array of length a (5).
Or use direct assignment,
var a = 5, arr = [];
while (a--) arr[a] = a;
for a slightly shorter, albeit slower, algorithm.
In the following code sample i get a strange behavior
var data = ['xxx', 'yyy'];
for (var i in data)
{
var a = i;
var b = data[i];
}
The two first iterations works just fine. I get index "0" and "1" in i, but then it loops one extra time and now the i is "sum". Is this by design or what is this extra iteration used for? The result in my case is always empty and it messes up my code. Is there a way to not do his extra loop?
BR
Andreas
It looks like you (or some other code you've included) have added extra properties onto the Array prototype. What you should be doing is checking to see whether the object you're iterating over actually has that property on itself, not on its prototype:
for (i in data) {
if (data.hasOwnProperty(i)) {
a = i;
b = data[i];
}
}
That said, you should never use for .. in on arrays. Use a regular for loop.
See here for more information: http://yuiblog.com/blog/2006/09/26/for-in-intrigue/
You are looping through an Array, not through an Object. For arrays it's better to use:
for (var i=0; i<data.length; i=i+1){
/* ... */
}
In your loop every property of the Array object is taken into account. That makes the for ... in loop for array less predictable. In your case it looks like sum is a property (method) that's added to Array.prototype elsewhere in your code.
There are more ways to loop through arrays. See for example this SO-question, or this one
Just for fun, a more esoteric way to loop an array:
Array.prototype.loop = function(fn){
var t = this;
return (function loop(fn,i){
return i ? loop(fn,i-1).concat(fn(t[i-1])) : [];
}(fn,t.length));
}
//e.g.
//add 1 to every value
var a = [1,2,3,4,5].loop(function(val){return val+1;});
alert(a); //=> [2,3,4,5,6]
//show every value in console
var b = [1,2,3,4,5].loop(function(val){return console.log(val), val;});
Here's a way to safely iterate.
var data = ['xxx', 'yyy'];
for (var i = 0; i < data.length; i++)
{
var a = i;
var b = data[i];
}
What you are getting is an method coming from extending the Array object, I guess you are using some library where is something like
Array.prototype.sum = function () {...};
Perhaps setting data like this would work better: var data = {0:'xxx', 1:'yyy'};
First of all data is an object. Try to add console.log(a); and console.log(b); inside your loop and you'll see.
I usually script/program using python but have recently begun programming with JavaScript and have run into some problems while working with arrays.
In python, when I create an array and use for x in y I get this:
myarray = [5,4,3,2,1]
for x in myarray:
print x
and I get the expected output of:
5
4
3
..n
But my problem is that when using Javascript I get a different and completely unexpected (to me) result:
var world = [5,4,3,2,1]
for (var num in world) {
alert(num);
}
and I get the result:
0
1
2
..n
How can I get JavaScript to output num as the value in the array like python and why is this happening?
JavaScript and Python are different, and you do things in different ways between them.
In JavaScript, you really should (almost) always iterate over an array with a numeric index:
for (var i = 0; i < array.length; ++i)
alert(array[i]);
The "for ... in" construct in JavaScript gives you the keys of the object, not the values. It's tricky to use on an array because it operates on the array as an object, treating it no differently than any other sort of object. Thus, if the array object has additional properties — which is completely "legal" and not uncommon — your loop will pick those up in addition to the indexes of the "normal" array contents.
The variable num contains the array item's index, not the value. So you'd want:
alert(world[num])
to retrieve the value
The for var in... loop in JavaScript puts the keys in the variable instead of the actual value. So when using for var ... you should do something like this:
var world = [5, 4, 3, 2, 1];
for ( var key in world ) {
var value = world[key];
alert(key + " = " + value);
}
And note that this way of looping is best used when you're using objects instead of arrays. For arrays use the common:
for ( var i = 0, j = arr.length; i < j; i++ ) { ... }
Or if you're targeting modern browser you can use the forEach-method of arrays:
var arr = [1, 2, 3];
arr.forEach(function(num) {
alert(num);
});
The for...in loop loops over all key elements; not the values.
I would recommend you to use
for(var i=0; i<arr.length; i++){
alert(arr[i]);
}
When you use the in operator num becomes a key. So simply use this key to get a value out of the array.
var world = [5,4,3,2,1]
for (var num in world) {
alert(world[num]);
}
try this.
var world = [5,4,3,2,1]
for(var i=0;i<world.length;i++){
alert(world[i])
}
Because javascript in your case is printing the index of the element, not the value.
the result you got is just element index,if you want to get element value
your code should like this
var world = [5,4,3,2,1]
for (var num in world) {
alert(world[num]);
}
The for in iteration in JavaScript works only for the object data type. The way it works is that it lets you iterate over the attributes of an object. arrays are objects in JavaScript, but the for in only works on its attributes, not the array values.
For example you might define an array as such:
var arr = [1,2,3];
And you can assign attributes to this array, because it's actually an object:
arr.foo = "bar";
arr["1"] = 2;
Now when you use the for in iteration method you will be able to iterate over the attributes we just assigned above;
for(var i in arr) console.log(i);
To iterate over the actual array values you need to use the for(var i=0; i<arr.length; i++) construct.
Hope this helps.
In javascript it's advised to loop Arrays different from looping Objects. You are using an object loop, which may return unexpected result (for instance if the Array.prototype was extended with custom methods you would iterate those too, and it does't guarantee the order of the array is preserved). There are many ways to loop through an array, using it's index:
// regular
var arr = [1,2,3,4,5]
,i
;
for (i=0;i<arr.length;i++) {
console.log(arr[i]);
}
// using while
var arr = [1,2,3,4,5]
,i = 0
;
while ((i = i + 1)<arr.length) {
console.log(arr[i]);
}
// using while reversed
var arr = [1,2,3,4,5]
,i = arr.length
;
while ((i = i - 1) > -1) {
console.log(arr[i]);
}
Note: Why not use i++ or i--? To avoid confusion, index out of range-errors and to satisfy JSLint