Reputation: 303
Basiclly what i am trying to do is for sort the values of a array input like uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1])
into a sorted 2D array like [[1, 1, 1], [2, 2, 2], [4], [3], [5]]
. The arrays don't have to be in number/ value order. The code below is what i tried:
function uniteUnique(arr) {
let times = 0;
var unique = [[]];
for (var i = 0; i < Array.prototype.slice.call(arguments).length; i++) {
times = 0;
for (var j = 0; j < arguments[i].length; j++) {
for (var h = 0; h < unique.length; h++) {
var pushArray = []
if(unique[h][0] === arguments[i][j]) {
unique[h].push(arguments[i][j])
arguments[i].splice(j)
}
else {
unique.push([arguments[i][j]])
}
}
}
}
return unique
}
uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);
--> https://repl.it/@John_Nicole/unique
I only have one parameter for all of the input arrays
I have a unique
array with 1 blank array. Its a 2D array.
Then i go through, for instance, the values of [1, 3, 2]
and check if any arrays in unique
have there first value as my number (arguments[i][j]
).
If true, i push the number arguments[i][j]
, then remove the number in the original array with splice()
.
If false, i push new array into unique
with this unrecognized value.
Quick Overview of the variables
h
: This is the array in unique
that i am going to compare with. It could be [2, 2, 2]
.i
: This is the array from the input. For instance, [1, 3, 2]
.j
: This the number itself, its partner with i
. For example, arguments[i][j]
= [2, 1]
--> 2
arguments
grabs all, in this case, the 3 input arrays.Times
: This just means 0. No use what so ever.The input could include 2D arrays in themselves like [1, 3, 2], [1, [5]], [2, [4]]
This is a part of a freeCodeCamp challenge --> https://www.freecodecamp.org/challenges/sorted-union
My question is that, why is my output:
[ [],
[ 1, 1 ],
[ 5, 5 ],
[ 5 ],
[ undefined, undefined ],
[ 2, 2 ],
[ 2 ],
[ 2 ],
[ 2 ],
[ 2 ],
[ undefined, undefined ],
[ undefined, undefined ],
[ undefined, undefined ],
[ undefined, undefined ] ]
?
when the wanted output is: Wanted output was [1, 1, 1], [2, 2, 2], [4], [3], [5]
Am i doing something wrong?
I'm getting multiple 2
's arrays for example ([[ 2 ],[ 2 ],[ 2 ],[ 2 ]]
) even though i'm suppose to be putting all 2
into one array?
Upvotes: 2
Views: 58
Reputation: 386560
You could use a hash table and check if the hash key exists and if not, then take an empty array as value for the hash and push it to the result set.
The hash table is an object (here without prototypes) which takes the values as keys and an array as value. A the the end the hash table keeps all values in arrays, which are inserted in the result set if a new value is found.
{ 1: [1, 1, 1], 2: [2, 2, 2], 3: [3], 4: [4], 5: [5] }
function uniteUnique() {
var result = [],
hash = Object.create(null);
Array.prototype.forEach.call(arguments, function (a) {
a.forEach(function (b) {
if (!(b in hash)) {
hash[b] = [];
result.push(hash[b]);
}
hash[b].push(b);
});
});
return result;
}
console.log(uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Some annotation to your code (not used variables are deleted):
function uniteUnique() {
var unique = [], // move all declarations to top
i, j, h,
pushed;
// array like objects have a length property
for (i = 0; i < arguments.length; i++) {
for (j = 0; j < arguments[i].length; j++) {
pushed = false;
for (h = 0; h < unique.length; h++) {
if (unique[h][0] === arguments[i][j]) {
// take the element, do not use splice, because with splicing
// the array becomes shorter and the index is updated in the
// next loop and is pointing to the element with the wrong index,
// because you get the element after next
// it is better not to mutate a variable, if it works without
// in this case, you iterate and visit each element only once
unique[h].push(arguments[i][j]);
pushed = true; // a value is found
break; // exit this loop
} // prevent more looping
}
if (!pushed) { // if not found
unique.push([arguments[i][j]]); // push the value
}
}
}
return unique;
}
console.log(uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1