Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
172
rated 0 times [  174] [ 2]  / answers: 1 / hits: 16500  / 7 Years ago, thu, may 4, 2017, 12:00:00

I am trying to remove duplicates from a list of arrays. The way I was trying to do this is by using reduce to create an empty array that pushes all undefined indexes onto that array. I am getting errors though that



if(acc[item]===undefined){
^
TypeError: Cannot read property '1' of undefined


my function below:





function noDuplicates(arrays) {
var arrayed = Array.prototype.slice.call(arguments);

return reduce(arrayed, function(acc, cur) {
forEach(cur, function(item) {
if (acc[item] === undefined) {
acc.push(item);
}
return acc;
});
}, []);
}

console.log(noDuplicates([1, 2, 2, 4], [1, 1, 4, 5, 6]));




More From » javascript

 Answers
0

There are a number of issues with how you're calling methods and where you return acc from:





function noDuplicates(arrays) {
var arrayed = Array.prototype.slice.call(arguments);

// reduce is a method of an array, so call it as a method
// return reduce(arrayed, function(acc, cur) {
return arrayed.reduce(function(acc, cur) {

// Same with forEach
cur.forEach(function(item) {
if (acc[item] === undefined) {
acc.push(item);
}
// Return acc from the reduce callback, forEach returns undefined always
// return acc;
});
return acc;
}, []);
}

console.log(noDuplicates([1, 2, 2, 4], [1, 1, 4, 5, 6]));





You could also call reduce directly on arguments using call:



Array.prototype.reduce.call(arguments, function(acc, curr) {
// ...
});


The above makes your code run, but it doesn't produce the correct output as the test:



  if (acc[item] === undefined)


doesn't do what you want. What you need to do is remember each value and only push it to acc if it's not been seen before:





function noDuplicates(arrays) {
var arrayed = Array.prototype.slice.call(arguments);
var seen = {};

return arrayed.reduce(function(acc, cur) {
cur.forEach(function(item) {
if (!seen[item]) {
acc.push(item);
seen[item] = true;
}
});
return acc;
}, []);
}

console.log(noDuplicates([1, 2, 2, 4], [1, 1, 4, 5, 6]));





Some other approaches:





// A more concise version of the OP
function noDupes() {
return [].reduce.call(arguments, function(acc, arr) {
arr.forEach(function(value) {
if (acc.indexOf(value) == -1) acc.push(value);
});
return acc;
},[]);
}

console.log(noDupes([1, 2, 2, 4], [1, 1, 4, 5, 6]));

// Some ECMAScript 2017 goodness
function noDupes2(...args){
return [].concat(...args).filter((v, i, arr) => arr.indexOf(v)==i);
}

console.log(noDupes2([1, 2, 2, 4], [1, 1, 4, 5, 6]));




[#57905] Tuesday, May 2, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
mahogany

Total Points: 645
Total Questions: 107
Total Answers: 98

Location: Israel
Member since Wed, Apr 14, 2021
3 Years ago
;