Reputation: 83
For example we have an array
const nums = [1,1,8,12,2,3,3,3,7];
If I want to map number of occurrences of each array member I could use something like
function extractDupes(arr) {
return arr.reduce(function (acc, item) {
if (item in acc) {
acc[item]++
}
else {
acc[item] = 1
}
return acc
}, {})
}
This would return object like
{ '1': 2, '2': 1, '3': 3, '7': 1, '8': 1, '12': 1 }
Is there an optimal way to filter out numbers which are showing up more than once just with using reduce (in a single pass) and have just
{ '1': 2, '3': 3 }
Upvotes: 1
Views: 226
Reputation: 827
It has been answered and accepted but anyhow here is how i would do.
const nums = [1, 1, 8, 12, 2, 3, 3, 3, 7];
const map = nums.reduce((acc, num) => {
acc.frequency[num] = (acc.frequency[num] || 0) + 1;
if (acc.frequency[num] > 1) {
acc.replicates[num] = acc.frequency[num];
}
return acc;
}, { frequency: {}, replicates: {} });
console.log(map);
Upvotes: 0
Reputation: 1606
const nums = [1,1,8,12,2,3,3,3,7];
const dups = {};
nums.forEach((v, i, s) => {
if (s.indexOf(v) != i)
if (dups[v])
dups[v]++;
else
dups[v] = 2;
});
console.log(dups);
If you also want the array of unique values at the end:
const nums = [1,1,8,12,2,3,3,3,7];
const dups = {};
const uniques = nums.filter((v, i, s) => {
if (s.indexOf(v) != i)
if (dups[v])
dups[v]++;
else
dups[v] = 2;
else
return true;
});
console.log(dups);
console.log(uniques);
Upvotes: 2
Reputation: 69
let arrAssist = [];
array.sort();
arrAssist.push(inventory[0]);
for(var i = 1; i < array.length; i++){
if(array[i] != array[i - 1]){
arrAssist.push(array[i]);
}
}
in this example, arrAssist
contains the array with no duplicates
Upvotes: 0
Reputation: 386634
You could take a nested property for the final object.
function extractDupes(array) {
return array
.reduce(function(acc, item) {
if (acc[item]) acc.dupes[item] = (acc.dupes[item] || 1) + 1;
else acc[item] = true;
return acc;
}, { dupes: {} })
.dupes;
}
const nums = [1, 1, 8, 12, 2, 3, 3, 3, 7];
console.log(extractDupes(nums))
Upvotes: 1
Reputation: 2806
have a staging variable for values equaling 1 and promote them to the main result when they're hit the second time?
const nums = [1,1,8,12,2,3,3,3,7];
function extractDupes(arr) {
const staging = {}
return arr.reduce(function (acc, item) {
if (item in acc) {
acc[item]++
} else if(item in staging) {
acc[item] = 2
delete staging[item]
} else {
staging[item] = 1
}
return acc
}, {})
}
document.getElementById('hi').innerHTML = JSON.stringify(extractDupes(nums))
<div id="hi"></div>
Upvotes: 1
Reputation: 14891
You could use Object.entries
to transform the object to key-value pairs then filter the pair that have value greater than 1, and then transform the pairs back to object by Object.fromEntries
const nums = [1, 1, 8, 12, 2, 3, 3, 3, 7]
function extractDupes(arr) {
return Object.fromEntries(
Object.entries(
arr.reduce(function (acc, item) {
if (item in acc) {
acc[item]++
} else {
acc[item] = 1
}
return acc
}, {})
).filter(([key, value]) => value > 1)
)
}
console.log(extractDupes(nums))
Upvotes: 0