I'm sure this is super simple, and I don't really want a complete solution, but pointing in the right direction as I'm learning.
I have:
let randomArray = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];
and the goal is to make it look like this, grouping like items:
[[1,1,1,1],[2,2,2],[10],[20,20],[391],[392],[591]]
My following code arranges, and groups fine. I push the temp to my Group array. But when I reset my "tempArray" to make it empty ready for the next "group", it removes the data from my group as well. Because it's linked? I assume? Maybe?
The only thing left at the end is the last item.
How do I stop it doing this?
// My SOlution
let randomArray = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];
let tempArray = [];
let groupArray = [];
function cleanTheRoom (arr) {
let ascendingArray = arr.sort(function(a,b) {
return a - b;
});
tempArray.push(randomArray[0])
for (let i = 1; i <= randomArray.length; i++) {
if (randomArray[i] === tempArray[0]) {
tempArray.push(randomArray[i])
} else {
groupArray.push(tempArray);
tempArray = []
tempArray.push(randomArray[i])
}
} console.log(groupArray)
}
cleanTheRoom(randomArray);
Use the concat function, like so: var arrayA = [1, 2]; var arrayB = [3, 4]; var newArray = arrayA. concat(arrayB); The value of newArray will be [1, 2, 3, 4] ( arrayA and arrayB remain unchanged; concat creates and returns a new array for the result).
The concat() method concatenates (joins) two or more arrays. The concat() method returns a new array, containing the joined arrays. The concat() method does not change the existing arrays.
concat() The concat() method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.
I took your code and changed some parts.
Array#sort
sorts in place. No need to assign to a new variable.
Iterate from zero and have a look to the data directly, by using the value at index minus one and at the index. If unequal, a new group is found. In this case just assign an empty array to groupArray
and push the group to the result.
Instead of using the same object reference and just empty the array by assigning zero to length
, this approach takes a new array.
Push the value outside of the if
statement, because it was doubled in then and else part.
Finally return the array with the groups.
function cleanTheRoom(array) {
let result = [];
let groupArray;
array.sort(function(a, b) {
return a - b;
});
for (let i = 0; i < array.length; i++) {
if (array[i - 1] !== array[i]) {
groupArray = [];
result.push(groupArray);
}
groupArray.push(array[i]);
}
return result;
}
let randomArray = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
console.log(cleanTheRoom(randomArray));
There are three main problems in your code:
You are using randomArray
inside the function but you should be using ascendingArray
tempArray.length = 0
- this statement mutates the original tempArray
and since you are pushing the tempArray
array in the groupArray
, changes to tempArray
are reflected in the groupArray
as well.
You could clone the tempArray
and push the copy of the tempArray
in the groupArray
groupArray.push([...tempArray]);
or you could assign the new empty array to tempArray
tempArray = [];
When its the last iteration of the loop, you are not pushing the contents of the tempArray
in the groupArray
. This will lead to the groupArray
not containing the last number in the sorted array, i.e. 591
. You need to check if the current iteration is the last iteration of the loop or not. If it is, push the tempArray
in the groupArray
for (let i = 1; i < ascendingArray.length; i++) {
...
if (i == ascendingArray.length - 1) {
groupArray.push(tempArray);
}
}
Here's a simplified version of your code:
let randomArray = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
function cleanTheRoom(arr) {
let tempArray = [];
let groupArray = [];
let ascendingArray = arr.sort(function (a, b) {
return a - b;
});
for (let i = 0; i < ascendingArray.length; i++) {
tempArray.push(ascendingArray[i]);
if (ascendingArray[i + 1] !== ascendingArray[i]) {
groupArray.push(tempArray);
tempArray = [];
}
}
console.log(groupArray);
}
cleanTheRoom(randomArray);
There might be even faster approaches but I took a quick shot at it:
I've used a Map instead of a dictionary for the groups because we can leverage the Map.set function neatly. It returns the whole Map which we need as the return value within the reduce.
const randomArray = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
const isGroup = (acc, number) => Array.isArray(acc.get(number));
const setGroup = (acc, number) => acc.set(number, isGroup(acc, number) ? acc.get(number).concat([number]) : [number]);
const unorderedNumberGroups = randomArray.reduce(setGroup, new Map());
const order = [...unorderedNumberGroups.keys()].sort((a, b) => a - b);
const orderedNumberGroups = order.reduce((acc, key) => acc.concat([unorderedNumberGroups.get(key)]), []);
console.log(orderedNumberGroups);
Here you go with a more debuggable version so you can try to understand the version above:
const randomArray = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
const isGroup = (acc, number) => Array.isArray(acc.get(number));
const unorderedNumberGroups = randomArray.reduce((acc, number) => {
if (isGroup(acc, number)) {
const mapEntry = acc.get(number);
const newEntry = mapEntry.concat([number]);
return acc.set(number, newEntry); // we need to return the acc, the Map.set method returns the whole Map
} else {
return acc.set(number, [number]); // we need to return the acc, the Map.set method returns the whole Map
}
}, new Map()); // initialize the accumulator we an empty Map
const keysAsArray = [...unorderedNumberGroups.keys()];
const order = keysAsArray.sort((a, b) => a - b);
const orderedNumberGroups = order.reduce((acc, key) => {
const arrayForTheKey = unorderedNumberGroups.get(key);
return acc.concat([arrayForTheKey]); // note the breakets!
// equivalent code:
// acc.push(arrayForTheKey);
// return acc;
}, []); // initialize the accumulator with an empty Array
console.log(orderedNumberGroups);
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