A task:
Write a function that takes an array and a number n. Then output an array in which there are no elements that are repeated more than n times.
Example:
Input:
n = 3;
arr = [1, 2, 4, 4, 4, 2, 2, 2, 2]
Output:
result = [1, 2, 4, 4, 4, 2, 2]
Tried to do something like that, but it's not working correctly.
let arr = [1, 2, 4, 4, 4, 2, 2, 2, 2];
let new_set = [...new Set(arr)];
let result = [];
console.log(new_set); // [1, 2, 4]
first:
for (let i = 0; i < arr.length; i ) {
if (arr[i] === arr[i - 1]) {
continue first;
}
else {
let count = 0;
for (let j = i; j < arr.length; j ) {
if ((arr[i] === arr[j]) && (count < 3)) {
result.push(arr[j]);
}
}
}
}
CodePudding user response:
You need a persistent outer variable that keeps track of how many times an item has been iterated over so far. Once past the limit, don't push the item being iterated over to the result.
const arr = [1, 2, 4, 4, 4, 2, 2, 2, 2]
let n = 3;
const counts = {};
const result = [];
for (const item of arr) {
counts[item] = (counts[item] || 0) 1;
if (counts[item] <= n) {
result.push(item);
}
}
console.log(result);
CodePudding user response:
Another option, if you want to use Array.reduce
.
It's not as optimised as @CertainPerformance as it uses a filter inside a loop. But for small arrays like this unlikely to make much difference.
const arr = [1, 2, 4, 4, 4, 2, 2, 2, 2]
let n = 3;
const result = arr.reduce((a,v)=>(
a.filter(f=>f===v).length < n ?a.push(v):a,a),[]);
console.log(result);
CodePudding user response:
Code golf version using reduce and without array.filter:
const f=(n,a)=>a.reduce((({c={},r=[]},i)=>
(c[i]??=0, c[i]>n?0:r.push(i),{c,r})),{}).r;
console.log(f(3, [1, 2, 4, 4, 4, 2, 2, 2, 2]).join());