Making An Array Flat, Understanding The Solution
Solution 1:
So your question is about this part of the code:
temp.unshift(1);
temp.unshift(l);
[].splice.apply(array, temp);
Starting with the last statement, it is calling splice
on array
, but in a specific way. Normally you would call it like this:
array.splice(l, 1, temp[0], temp[1], ...)
... which means: at index l
of array
, delete 1 element, and insert temp[0]
, temp[1]
, ... etc. The problem is that we don't know beforehand how many elements there are in temp
, but still need to provide as many arguments to splice
. And we can't just pass temp
as argument, because then array
gets an element inserted that is an array itself, which is what you just do not want to do.
While in ES6 there is an easy solution for this (see below), in ES5 you can solve this by using apply
on splice
. That apply
method accepts as first argument the object to apply the function on, and then an array which has all arguments that need to be passed to that function.
As the first two of those arguments have the meaning of index, and the number of elements to delete there (see above), and only then the remaining arguments represent which elements need to be inserted (those in temp
), there is all this shifting happening: these insert the two first arguments to pass to splice
.
Then the remaining arguments are what originally was in temp
(before the shifting). You could say that the shift
and apply
statements do the following:
array.splice(temp[0], temp[1], temp[3], temp[4], ...)
Note how temp
is playing a role for all the arguments now. And that is why the first two values were shifted in. It looks complicated, and although it works, it does not result in very readable code.
Now in ES6 it has become much simpler. You can now use the spread operator to kind of explode an array into different arguments, and functions can deal with that:
array.splice(l, 1, ...temp)
And since we don't need to shift anymore, we can safely do this without the variable temp
, and directly on array[l]
. So the complete code would look like this:
function flatten(array) {
var l = array.length;
while (l--) {
if (Array.isArray(array[l])) {
flatten(array[l]);
array.splice(l, 1, ...array[l]);
}
}
}
var array = [['1', '2', '3'], ['4', '5', ['6'], ['7', '8']]];
flatten(array);
console.log(array);
Isn't that nice and simple? ;-)
Solution 2:
I recognize the challenge from fcc .. but that's an insanely complicated way to do it. This is how is solved it.
function flatten(arr) {
return arr.reduce(function (flat, toFlatten) {
return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
}, []);
}
function steamroller(arr) {
return flatten(arr);
}
steamroller([1, [2], [3, [[4]]]]);
The solution you posted is insanely complicated and messy and broken, the unshifts at the end simply add 1,1 to the beginning of the array, it's a dirty way to pass the challenge ...
Solution 3:
I would do this job like this;
var a =[['1', '2', '3'], ['4', '5', ['6'], ['7', ['8','9']]]];
Array.prototype.flat = function(){
return this.reduce((p,c) => Array.isArray(c) ? p.concat(...c).flat() : p.concat(c),[]);
};
var b = a.flat();
console.log(JSON.stringify(b));
Solution 4:
Splice is a function which takes the index to start at, the number of elements to remove, and 0+ elements to insert inside of the hole you left.
Apply is a method that functions have (yes, functions are objects and have methods).
It takes a this
and then it takes an array of arguments to pass in.
When you have no idea how many elements you have, but you need to pass them all to a function:
// instead of
fn(a, b, c, d, e, f, g);
// you can say
fn.apply(null, args); // args being an array of arbitrary length
So you can then say:
array.splice.apply(array, args);
Where args should be the index, the number to remove, and then an arbitrary list of elements to put inside of that hole.
The []
is just a throw-away array to have quick access to splice
(to call it with apply
).
Post a Comment for "Making An Array Flat, Understanding The Solution"