Leed
Leed

Reputation: 303

Sorting arrays (2D array) Need assistance

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 uniquearray 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 uniquehave 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

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

Answers (1)

Nina Scholz
Nina Scholz

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

Related Questions