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]]

5
  • 1
    please add the wanted result. Commented Feb 18, 2020 at 8:08
  • Do you mean d1 should be gone from the result? Commented Feb 18, 2020 at 8:12
  • Does this answer your question? How to compare arrays in JavaScript? Commented Feb 18, 2020 at 8:13
  • @NinaScholz sorry i have added output , will be like : [[1,2,3],[4,4,5],[3,4,5]] Commented Feb 18, 2020 at 8:20
  • @tevemadar yes d1 is duplicate Commented Feb 18, 2020 at 8:38

4 Answers 4

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; }

Sign up to request clarification or add additional context in comments.

3 Comments

@user889030 would you consider [4,4,5] and [4,5,4] duplicates of each other? Because this code does (that's what the sort() is doing there)
@tevemadar no local indexing sorting is not required
if you do not need a sorting, you could take an object as well.
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.

Comments

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%;}

2 Comments

hmmm there is one duplicate [4,4,5] , output seems wrong
arrays comparison logic was flawed, got it fixed now
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]]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.