1

I am trying to remove duplicates from my 2D array but no success.

Here is what I am doing any idea where am making mistake?

function Remove_duplicates_from_2d_array(data_array) {
  if (data_array.length > 0) {
    let unique_index_counter = 0;
    // loop on target array
    for (var a = 0; a < data_array.length; a++) {
      var unique_array = data_array[unique_index_counter];

      if (a === unique_index_counter) {
        continue;
      }
      console.log('comparing index: ' + a + ' ( ' + data_array[a] + ' ) -- index: ' + a + ' ( ' + data_array[a] + ' )');
      if (data_array[a].sort().join(',') === unique_array.sort().join(',')) {
        console.log('match it index ' + a + ' - ' + unique_index_counter);
        // same arrays
        data_array.splice(a, 1);
        a = 0; // reset for loop as splice will rebuilt array 
      }
      // a will be equal to data_array length incase there is no match found 
      if (a === data_array.length) {
        unique_index_counter++;
      }
   if(unique_index_counter != data_array.length) {
  a = 0; // reset for loop because we have not checked all items 
   }
    }

    return data_array;
  } else {
    return [];
  }
}

var a1 = [1, 2, 3];
b1 = [4, 4, 5];
c1 = [3, 4, 5];
d1 = [4, 4, 5];
var data_array = [];
data_array.push(a1);
data_array.push(b1);
data_array.push(c1);
data_array.push(d1);
console.log('original array.');
console.log(data_array);

var r = Remove_duplicates_from_2d_array(data_array);
console.log('unique array.');
console.log(r);  // [[1,2,3],[4,4,5],[3,4,5]]
user889030
  • 4,353
  • 3
  • 48
  • 51

4 Answers4

2

You could take a Set for seen sorted string and filter the array by checking the occurences.

function removeDuplicates(array) {
    var seen = new Set;
    return array.filter(a => (s => !seen.has(s) && seen.add(s))(a.join()));
}

console.log(removeDuplicates([[1, 2, 3], [4, 4, 5], [3, 4, 5], [4, 4, 5]]));
// [[1, 2, 3], [4, 4, 5], [3, 4, 5]]
.as-console-wrapper { max-height: 100% !important; top: 0; }

With an object.

function removeDuplicates(array) {
    var seen = {};
    return array.filter(v => !seen[v] && (seen[v] = true));
}

console.log(removeDuplicates([[1, 2, 3], [4, 4, 5], [3, 4, 5], [4, 4, 5]]));
// [[1, 2, 3], [4, 4, 5], [3, 4, 5]]
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

You may Array.prototype.reduce() source array doing Array.prototype.find()'ing duplicates along the way:

const src = [[1,2,3],[4,4,5],[3,4,5],[4,4,5]],
      arrsAreEqual = (a1,a2) => a1.sort().join('|') === a2.sort().join('|'),
      dedupe = src.reduce((r,a) => 
        (!r.find(ra => arrsAreEqual(a,ra)) && r.push(a), r), [])
      
console.log(JSON.stringify(dedupe))
.as-console-wrapper{min-height:100%;}
Yevhen Horbunkov
  • 14,965
  • 3
  • 20
  • 42
1

Sets are nice and all, but you may benefit from seeing a simple for-based approach too:

var orig = [[1, 2, 3],
            [4, 4, 5],
            [3, 4, 5],
            [4, 4, 5]];

function undupe(arr){
  let ret=[];
  for(let candidate of arr){
    let found=false;
    for(let line of ret){
      let linematch=true;
      for(let i=0;i<line.length;i++){
        if(candidate[i]!==line[i]){
          linematch=false;               // if one element does not match, the lines are different
          break;                         // and the rest does not matter
        }
      }
      if(linematch){
        found=true;                      // if all elements matched, candidate is a duplicate
        break;                           // remaining lines do not matter
      }
    }
    if(!found){
      ret.push(candidate);               // candidate is unique, add it to the result
    }
  }
  return ret;
}

console.log(undupe(orig));
  • candidate loop gets all items in the input array
  • line loop gets all items from ret array, so the items which are unique so far
  • i loop compares the actual numbers (one from candidate with the corresponding one from line)
  • these loop things are slow at large data sizes, so it is a good idea to terminate them as soon as possible. Like when the first elements do not match in a pair of lines, they are different for sure, there is no need to check the rest.

Of course it could be more structured, like

var orig = [[1, 2, 3],
            [4, 4, 5],
            [3, 4, 5],
            [4, 4, 5]];
            
function linesmatch(line1,line2){
  for(let i=0;i<line1.length;i++)
    if(line1[i]!==line2[i])
      return false;
  return true;
}

function isdupe(arr,line){
  for(let l of arr)
    if(linesmatch(l,line))
      return true;
  return false;
}

function undupe(arr){
  let ret=[];
  for(let candidate of arr)
    if(!isdupe(ret,candidate))
      ret.push(candidate);
  return ret;
}

console.log(undupe(orig));

This would be the more textbook-like variant with small, readable functions built on top of each other.

tevemadar
  • 12,389
  • 3
  • 21
  • 49
0

here is my fixed simple version of duplicate remover based on for loop

function Remove_duplicates_from_2d_array(data_array) {
    var unique_array = [];
  if (data_array.length > 0) {
    let unique_index_counter = 0; 
    // loop on target array
    for (var a = 0; a < data_array.length; a++) {
      // if have same indexs , skip
      if (a === unique_index_counter) {
         continue;
      }
        // compare both indexes
      if (data_array[unique_index_counter].join(',') == data_array[a].join(',') ) {
            data_array.splice(a, 1);  // remove that a index 
            a = 0; // reset for loop as splice will rebuilt array 
            continue;
      }
      // a will be equal to data_array length incase there is no match found 
      else if ( (data_array.length != 0 && a == data_array.length - 1)  ) {
        unique_array.push(data_array[unique_index_counter]);  // push unique index to unique array
        data_array.splice(unique_index_counter, 1);  // remove that a index 
        a = 0; // reset for loop as splice will rebuilt array 
      }
    } // for end
     // by now one unique element will be still left in source arrays
     unique_array.push(data_array[0]);  // push unique index to unique array

    return unique_array;
  } else {
    return [];
  }
}

var a1 = [1, 2, 3];
b1 = [4, 4, 5];
c1 = [3, 4, 5];
d1 = [4, 4, 5];
var data_array = [];
data_array.push(a1);
data_array.push(b1);
data_array.push(c1);
data_array.push(d1);
console.log('original array.');
console.log(data_array);

var r = Remove_duplicates_from_2d_array(data_array);
console.log('unique array.');
console.log(r);  // [[1,2,3],[4,4,5],[3,4,5]]
user889030
  • 4,353
  • 3
  • 48
  • 51