I am trying to recreate the underscore js function difference using reduce. Difference takes in multiple arrays and returns all values that are similiar to the first array. so [1,2],[2,3],[1,3] should spit out [1,2,2,1].
I was thinking of looping through each of my subarray(rest) and if the value of my sub elements has an index in my first array then I will push that element onto my accumulator value(which is an empty array).
Some reason I do not get my intended output where I was expecting [1,2,3,2,1,2]. instead I am getting [ [ 1, 2 ], [ 2, 4 ], [ 1, 2 ] ]. Can anyone help me with this rewrite using reduce. Thanks.
function difference(arrays){
var arrayed=Array.prototype.slice.call(arguments);
var first=arrayed[0];
var rest=arrayed.slice(1);
return reduce(first,function(acc,cur){
forEach(rest,function(sub){
if (sub.indexOf(cur)>-1){
acc.push(sub);
}});
return acc;
},[]);
}
console.log(difference([1,2,3],[2,4],[1,2],[4,5]));
i know the way im calling forEach is different but it is because my own version of forEach accepts two arguments.
Here's a solution :
function difference(arrays){
var arrayed = Array.prototype.slice.call(arguments);
var first = arrayed.splice(0,1)[0]; // edit, thanks robG
var tmp = [];
return arrayed.reduce(function(acc, arr) {
return acc.concat(arr.filter(function(el) {
return first.includes(el);
}));
}, first);
}
console.log(difference([1,2,3],[2,4],[1,2],[4,5]));
Use the javascript reduce
method on the 'rest' array, makes the first array be the default value of the accumulator, filter the arrays with the first one and concat the result to your accumulator.
Hope it helps,
best regards
Could try this
function difference(arrays){
var arrayed=Array.prototype.slice.call(arguments);
var first=arrayed[0];
var rest=arrayed.slice(1);
return first.concat(rest.reduce(function(acc, cur, curIndex, array){
first.forEach(function(eachEle){
if(cur.indexOf(eachEle) > -1 )
acc.push(cur[cur.indexOf(eachEle)]);
});
return acc;
}, []));
}
console.log(difference([1,2,3],[2,4],[1,2],[4,5]));
As for your previous question , you need to call array methods on arrays, not pass them as parameters so not
return reduce(first,function(acc,cur){...})
but
return first.reduce(function(acc,cur){...});
In your function:
var first=arrayed[0];
var rest=arrayed.slice(1);
can be replaced with one step using splice:
var first = arrayed.splice(0, 1)
and use arrayed instead of rest . But there's no need for that anyway. If no accumulator is provided, then the first value is used, so (with some renaming of variables):
function difference(){ var args = Array.prototype.slice.call(arguments); return args.reduce(function(acc, cur){ cur.forEach(function(value){ if (acc.includes(value)){ acc.push(value); } }); return acc; }); } console.log(difference([1,2,3],[2,4],[1,2],[4,5]));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.