Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function to return distinct values in a 2D array

Tags:

javascript

I have the following 2D array

var items = [['al','bv','sd'],
             ['al','cc','ab'],
             ['cv','vv','sw'],
             ['al','bv','sd']
            ];

I need a function which will return me a similar array but with distinct values. For example, in the above array, ['al','bv','sd'] happens twice.

I would like the function to return me:

var items = [['al','bv','sd'],
             ['al','cc','ab'],
             ['cv','vv','sw']
            ];
like image 899
tanya Avatar asked Jan 27 '12 15:01

tanya


3 Answers

Quick and dirty solution, assuming the data is small.

On each iteration, convert the row to a string. Use a dictionary to store the string with a value of True, if it is not already in the map. Also, add it to your output array. If it is already in the dictionary, go to the next item.

Example:

var d = {};
var out = [];
for( var i = 0; i < items.length; i++ ) {
    var item = items[i];
    var rep = item.toString();

    if (!d[rep]) {
        d[rep] = true;
        out.push(item);
    }
}

// out has the result
like image 104
yas Avatar answered Sep 28 '22 09:09

yas


You have to loop two (or three times):

  1. Loop through all "rows", from beginning to the end
  2. Loop again, through all "rows", from beginning to the end

    • If the lists are equal, ignore it
    • Otherwise,
  3. Loop through all "columns":

    • If the values are not equal, jump to the parent loop.
    • After the loop, remove the element using the .splice method.

Demo: http://jsfiddle.net/EuEHc/

Code:

for (var i=0; i<items.length; i++) {
    var listI = items[i];
    loopJ: for (var j=0; j<items.length; j++) {
        var listJ = items[j];
        if (listI === listJ) continue; //Ignore itself
        for (var k=listJ.length; k>=0; k--) {
            if (listJ[k] !== listI[k]) continue loopJ;
        }
        // At this point, their values are equal.
        items.splice(j, 1);
    }
}
like image 30
Rob W Avatar answered Sep 28 '22 10:09

Rob W


An unconventional but easier to code version

var items = [['al','bv','sd'],
             ['al','cc','ab'],
             ['cv','vv','sw'],
             ['al','bv','sd']
            ];

var temp = {};

for ( var i in items ) {
    var serialized = JSON.stringify(items[i]);
    if ( temp[serialized] ) {
        items.splice( i, 1 );
        continue;
    }
    temp[serialized] = true;
} 

Try it here! http://jsfiddle.net/y3ccJ/1/

More conventional option:

var items = [['al','bv','sd'],
             ['al','cc','ab'],
             ['cv','vv','sw'],
             ['al','bv','sd']
            ];

var results = [];

loop: for ( var i in items ) {
    compare: for ( var j in results ) {
        for ( var k in items[i] ) {
            if ( items[i][k] !== results[j][k] ) {
                break compare;
            }
        }
        continue loop;
    }
    results.push( items[i] );
}

http://jsfiddle.net/xhrd6/

like image 31
Davide Avatar answered Sep 28 '22 10:09

Davide