I am pretty new to javascript, and I was trying to build this function I found in a challenge. I have managed to solve this, but I feel like this is a very complicated way of doing things, what would be the fastest method here?
Basically answer(array) should transform this:
const array = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];
into this:
newArray = [[1,1,1,1],[2,2,2], 4,5,10,[20,20], 391, 392,591];
Here is my code so far:
const array = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
const duplicates = arr =>
arr.reduce((a, b) => ({ ...a,
[b]: (a[b] || 0) + 1
}), {})
array.sort((a, b) => a - b);
let array1 = duplicates(array);
var values = Object.values(array1);
var keys = Object.keys(array1);
var newArray = [];
for (let i = 0; i < keys.length; i++) {
let tempArray = [];
for (let j = 0; j < values[i]; j++) {
tempArray.push(keys[i]);
}
newArray.push(tempArray);
}
console.log(newArray);
duplicates function comes from This post about finding duplicate values
Have a look at this one-liner. Guess this is what you need.
Note that this isn't the most efficient way to to this - but guess it's beautyfull!
const array = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];
const newArray = [...new Set(array)].sort((a, b) => a-b).map(e => new Array(array.filter( i => i === e).length).fill(e)).map(e => e.length === 1 ? e[0] : e);
console.log(newArray);
How this works:
[...new Set(array)]
.sort((a, b) => a-b)
.map(e => new Array(array.filter( i => i === e).length);
.fill(e)
.map(e => e.length === 1 ? e[0] : e)
Your approach is good enough (fast). I made some modifications to use parseInt()
on keys to convert the keys back to number from string. And also made sure that a single element is not nested (as your expected output in your OP.
const array = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
const duplicates = arr =>
arr.reduce((a, b) => ({ ...a,
[b]: (a[b] || 0) + 1
}), {})
array.sort((a, b) => a - b);
let array1 = duplicates(array);
var values = Object.values(array1);
var keys = Object.keys(array1);
var newArray = [];
for (let i = 0; i < keys.length; i++) {
let tempArray = [];
if (values[i] === 1) {
newArray.push(parseInt(keys[i]));
} else {
newArray.push(Array(values[i]).fill(parseInt(keys[i])));
}
}
console.log(newArray);
Given the sorted array (ascending), you could have 2 variables, one storing the sorted unique array of element, one storing the occurrence of element in the array
After that, you map through the unique, if the occurence is greater than one, return an array filled by the element with the length of that element's occurrence, else just return that element
const sortedArray = [1, 1, 1, 1, 2, 2, 2, 4, 5, 10, 20, 20, 391, 392, 591]
const sortedUnique = Array.from(new Set(sortedArray))
const occurences = sortedArray.reduce((acc, el) => {
acc.set(el, (acc.get(el) || 0) + 1)
return acc
}, new Map())
const res = sortedUnique.map((el) =>
occurences.get(el) > 1 ? Array(occurences.get(el)).fill(el) : el
)
console.log(res)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With