Reputation: 337
Is there a way through functions or array methods to spread an array without the spread operator. I was solving Algo challenges on FCC and was just curious about this.
function uniteUnique(arr) {
var args = [].slice.call(arguments);
var newArr = [];
args.forEach(arr => newArr.push(...arr));
return newArr.reduce((array, num) => {
if(!array.includes(num)) {
array.push(num);
}
return array;
}, []);
}
Upvotes: 1
Views: 3676
Reputation: 12657
var args = [].slice.call(arguments);
var newArr = [];
args.forEach(arr => newArr.push(...arr));
this part of your code is just flattening the arguments by one level, and can also be written as
var newArr = [].concat.apply([], arguments);
and
return newArr.reduce((array, num) => {
if(!array.includes(num)) {
array.push(num);
}
return array;
}, []);
is returning a version of that without duplicates. Wich can also be achieved differently
//adding that, because it's so much simpler than your reduce
return [...new Set(newArr)];
return Array.from(new Set(newArr));
//or
return newArr.filter(function(v,i){ return newArr.indexOf(v) === i });
and the whole thing
function uniteUnique( /*...arrays*/ ) {
return [].concat.apply([], arguments)
.filter(function(v, i, a) {
return a.indexOf(v) === i
});
}
console.log(uniteUnique(
1,
[2, 3, 4],
2,
[3, 5],
[2, 4, 6, 8],
8,
[1, 3, 5, 7, 9]
));
.as-console-wrapper{top:0;max-height:100%!important}
If you want to flatten by multiple (all) levels, you can do this like
//reusable helper
function _flatten(into, value){
if(Array.isArray(value))
return value.reduce(_flatten, into);
into.push(value);
return into;
}
function _unique(v,i,a){
return a.indexOf(v) === i;
}
function uniteUnique( /*...arrays*/ ) {
return _flatten([], [].slice.call(arguments))
.filter(_unique);
}
or the all-in-one solution
function uniteUnique( /*...arrays*/ ) {
return (function _recursive(into, value){
if(Array.isArray(value))
return value.reduce(_recursive, into);
if(into.indexOf(value) === -1) into.push(value);
return into;
})([], [].slice.call(arguments));
}
Upvotes: 1
Reputation: 6381
const newArray = [...oldArray];
will produce identical output as using Array.prototype.concat:
const newArray = [].concat(oldArray)
if you want to merge all arrays into one then you can do it with Array.prototype.reduce:
const newArray = args.reduce((acc, arr) => acc.concat(arr), [])
Upvotes: 0
Reputation: 26909
Use Function.prototype.apply()
. Consider this article about emulating spread with apply()
: Using 'apply' to Emulate JavaScript's Upcoming Spread Operator.
function uniteUnique(arr) {
var args = [].slice.call(arguments);
var newArr = [];
args.forEach(arr => Array.prototype.push.apply(newArr, arr));
return newArr.reduce((array, num) => {
if(!array.includes(num)) {
array.push(num);
}
return array;
}, []);
}
Upvotes: -1