Array.From() different results - javascript

if you run this javascript on this page:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
you get the following result:
console.log(Array.from([1, 2, 3], x => x + x));
// expected output: Array [2, 4, 6]
> Array [2, 4, 6]
if you run the same code in the chrome console on this page(https://portal.fellowshipone.com/) i get this result:
console.log(Array.from([1, 2, 3], x => x + x));
// expected output: Array [2, 4, 6]
VM2786:1 (3) [1, 2, 3]
Why does this occur?

The page you are referring to is using Array.from from the Prototype library. Try to enter Array.from to the console and you will see that this function is declared in an external library which overrides native implementation.

Related

Why spread operator turn my array into numbers

i have
a = [[1,2,3],[4,5,6]]
How come when i write
console.log(...a.shift())
it gives me 1 2 3
but not 1,2,3 nor [1, 2, 3]
can anyone explain me the mechanism behind this?
a.shift() returns the first element of the array, which is [1, 2, 3]. So your code is equivalent to:
console.log(...[1, 2, 3])
The spread syntax causes each element of the array to become a separate argument, so this is equivalent to
console.log(1, 2, 3)
which prints each number separately on the console.
To get [1, 2, 3] you shouldn't use ..., just write
console.log(a.shift())
To get 1,2,3 use
console.log(a.shift().join(','))
console.log(...a.shift())
is run in given order:
a.shift() returns [1, 2, 3] => console.log(...[1, 2, 3])
...[1, 2, 3] is evaluated into 1 2 3 and passed to console.log as 3 different arguments => console.log(1, 2, 3)
Which has out of 1 2 3

Why do some operations not alter an array that was passed to a function?

Scenario 1:
var myArray = [2, 3, 4, 5];
function doStuff(arr) {
arr = [];
}
doStuff(myArray);
console.log(myArray); // [2,3,4,5]
Scenario 2:
var myArray = [2, 3, 4, 5];
function doStuff(arr) {
arr.pop();
}
doStuff(myArray);
console.log(myArray); // [2,3,4]
Why does scenario 1 not update the globally declared array but scenario 2 does?
In the first example:
You are altering the variable arr which is merely just holding a reference to the array [2, 3, 4, 5], so instead of holding a reference to [2, 3, 4, 5], it will hold a reference to another array [].
At the line var myArray = [2, 3, 4, 5];:
myArray -----------------------------------> [2, 3, 4, 5]
Then at the line doStuff(myArray);:
myArray -----------------------------------> [2, 3, 4, 5]
↑
arr ----------------------------------------------/
Then at the line arr = [];:
myArray -----------------------------------> [2, 3, 4, 5]
arr ---------------------------------------> []
=> So, after the call to doStuff, myArray is still [2, 3, 4, 5].
In the second example:
You are using the reference to [2, 3, 4, 5] stored in arr to call a function pop on it that alters it.
At the line var myArray = [2, 3, 4, 5];:
myArray -----------------------------------> [2, 3, 4, 5]
Then at the line doStuff(myArray);:
myArray -----------------------------------> [2, 3, 4, 5]
↑
arr ----------------------------------------------/
Then at the line arr.pop();:
myArray -----------------------------------> [2, 3, 4, 5].pop()
↑
arr.pop() ----------------------------------------/
Which alters the array to:
myArray -----------------------------------> [2, 3, 4]
↑
arr ----------------------------------------------/
=> So, after the call to doStuff, myArray is now [2, 3, 4].
In the first case you are doing a new memory allocation while you are actually modifying the array in the second case.
Hence in the first case the value does not get modified.
For eg:
var myArrayOne = [2, 3, 4, 5];
function doStuff(arr) {
arr = [7,8,9]; //assigining a whole new object to the copy
}
doStuff(myArrayOne);
console.log(myArrayOne); // [2,3,4,5]
// Scenario 2
var myArrayTwo = [2, 3, 4, 5];
function doStuff(arr) {
arr.pop(); //modifying the internals of the arr object
}
doStuff(myArrayTwo);
console.log(myArrayTwo); // [2,3,4]
arr is a reference to the array, which exists somewhere in memory (you don't know where, and you don't care). When you say arr = [], you're creating a new array somewhere in memory, and changing arr to refer to that new array. The old array still exists in memory. If there was nothing referring to the old array then it would eventually be garbage collected, but in this case it's still referred to by myArray so it remains untouched.
arr.pop() on the other hand is modifying the array, not changing references.
In the first function, you're just reassigning the parameter of the function. That has no effect on the passed data.
In the second, you're actually mutating the passed array via the call to pop.
Think of it this way: in
var a = 1
a = 2
Is the 1 modified in any way? No, the reference a that was pointing to it was just changed.

Merging the elements of nested arrays into one big array

I'm trying to merge the elements of the array into one big array. But I receive a message saying:
ReferenceError: reduce is not defined
Here is my code:
var arrays = [[1, 2, 3], [4, 5], [6]];
console.log(reduce(arrays, function(arrayOne, arrayTwo){
return arrayOne.concat(arrayTwo);
}, 0));
reduce() is a method of the Array object, so you must use arrays.reduce().
Moreover, since your initial value is set to 0 (the 2nd parameter), you can't use arrayOne.concat on it, since it's not an array, so you must set the initial value to [].
var arrays = [[1, 2, 3], [4, 5], [6]];
console.log(arrays.reduce(function(arrayOne, arrayTwo){
return arrayOne.concat(arrayTwo);
}, []));
Note that calling Array.flat is easier:
var arrays = [[1, 2, 3], [4, 5], [6]];
// If you expect a multi-level nested array, you should increase the depth.
var depth = 1;
console.log(arrays.flat(depth));
reduce() is only defined on Arrays, you cannot call it by itself:
arrays.reduce(
function (a, b) { return a.concat(b); }
);
// Array [ 1, 2, 3, 4, 5, 6 ]

What is .apply doing in this JavaScript code?

I am doing the Netflix tutorial on Reactive Programming and I came across this piece of code that I don't fully understand.
Array.prototype.mergeAll = function() {
var results = [];
this.forEach(function(subArray) {
results.push.apply(results, subArray);
});
return results;
};
Why use apply in this line of code results.push.apply(results, subArray);? Why not just use results.push(subArray)? What is the difference in the code?
The results wouldn't be the same at all. You can test this for yourself:
results = [1, 2, 3];
subArray = [4, 5, 6];
results.push(subArray);
console.log("With push:", results); // With push: [1, 2, 3, [4, 5, 6]]
results = [1, 2, 3]; // reset results
results.push.apply(results, subArray);
console.log("With apply:", results); // With apply: [1, 2, 3, 4, 5, 6]
apply accepts an array of arguments, and the elements of the array become individual arguments to the function.
This lets you invoke the function push with an arbitrary number of arguments, where each argument is added to the array. Simply calling results.push(...) would invoke the function with a single argument, which would be an array, resulting in the entire subArray being pushed onto results as one element.
In the above example, results.push.apply(results, subArray) is equivalent to calling results.push(4, 5, 6), while results.push(subArray) simply invokes results.push([4, 5, 6]).
The net effect of using one over the other is that, given an input array containing sub-arrays...
[[1, 2, 3], [4, 5, 6], [7, 8], [9]]
... using results.push would produce an identical array, where each sub-array was pushed onto results as a single element:
[[1, 2, 3], [4, 5, 6], [7, 8], [9]]
Using results.push.apply would cause each element from each sub-array to be pushed onto results as its own element, resulting in the desired flattened array:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Example 1:
var results = [];
results.push.apply(results,[2,3,4])
results [2,3,4]
Example 2:
var results2 = [];
[].push.apply(results2,[2,3,4])
// results2 [2,3,4]
results.push.apply is identical to [].push.apply. Both of them represent array's push method.
the first parameter in apply() method : results / results2, representing the scope/this inside Array.prototype.push method.
Here is the link giving a good example, how the first parameter in apply() method works.
If you want to know, why the second parameter of apply() method is array of arguments. This link's example has good explanation.
Basically
[].push.apply(results2,[2,3,4])
// results2 [2, 3, 4]
result2.push(2,3,4)
// results2 [2, 3, 4]
The first method is equal to the second method

underscore.js - Is there a function that produces an array thats the difference of two arrays?

Looking for a function in underscore.js that will take 2 arrays and return a new array of unique values? Something like _without
_.without([0, 1, 3, 9], [1, 3]);
I would like => [0,9] returned
It appears _without's 2nd arg is a list of values, not an array. Anyone out there know
if underscore has the specific function I'm looking for? Or can I take an exisitng array and covert it to values the function expects.
Thanks,
~ck in San Diego
The _.difference function should give you what you're looking for:
_.difference([0, 1, 3, 9], [1, 3]); // => [0, 9]
_.without.apply(_, [arr1].concat(arr2))
[[0, 1, 3, 9]].concat([1, 3]) is [[0, 1, 3, 9], 1, 3];
_.without.apply(_, [[0, 1, 3, 9], 1, 3]) is _.without([0, 1, 3, 9], 1, 3)
You've got a perfectly good _.without method. So just convert an array into a list of values you can pass into a function. This is the purpose of Function.prototype.apply
var result = _.reject([0, 1, 3, 9], function(num) {
return _.include([1, 3], num);
});
Lo-Dash is extended Underscore and here is what you need: http://lodash.com/docs#xor
_.xor
Creates an array that is the symmetric difference of the provided arrays. See http://en.wikipedia.org/wiki/Symmetric_difference.
_.xor([1, 2, 3], [5, 2, 1, 4]);
// → [3, 5, 4]

Categories

Resources