Home > database >  Remove similar duplicates from 2D array in JavaScript
Remove similar duplicates from 2D array in JavaScript

Time:01-11

I need to remove similar duplicates as well as real duplicates from 2D array in JavaScript.

let a = [
  [5, 6],
  [1,1],
  [6,5],
  [1,1],
  [3,2],
  [2,3]
]

function makeUnique(arr) {
  var uniques = [];
  var itemsFound = {};
  for(var i = 0, l = arr.length; i < l; i  ) {
      var stringified = JSON.stringify(arr[i]);
      if(itemsFound[stringified])  continue; 
      uniques.push(arr[i]);
      itemsFound[stringified] = true;
  }
  return uniques;
}

a=makeUnique(a)
console.log(a);

I have got this output:

[ [ 5, 6 ], [ 1, 1 ], [ 6, 5 ], [ 3, 2 ], [ 2, 3 ] ]

Correct should be:

[ [ 5, 6 ], [ 1, 1 ], [ 2, 3 ] ]

My code removes correctly duplicates, but I need to remove similar duplicates also.

For example if I have [3,2] and [2,3] I should remove [3,2] (the one which has bigger starting index value.)

Could you help me to fix this?

CodePudding user response:

Here is an example of how you can do it:


function makeUnique(arr) {
    var uniques = [];
    var itemsFound = {};
    arr.sort((a, b) => a[0]   a[1] - (b[0]   b[1]))
    for (var i = 0, l = arr.length; i < l; i  ) {
        if (!itemsFound[arr[i]] && !itemsFound[[arr[i][1], arr[i][1]]]) {
            uniques.push(arr[i]);
            itemsFound[arr[i]] = true;
            itemsFound[[arr[i][1], arr[i][0]]] = true;
        }
    }
    return uniques;
}

I hope it helps.

CodePudding user response:

there are two parts

  1. similar should be considered
  2. among similar , one with smaller first key should stay

1. similar should be considered

here you can just make the key for hashmap in such a way that similar items produce same key

one way to do that is sort the items in the tuple and then form the key, as there are two items only , first one will be min and second one will be max

let a = [
  [5, 6],
  [1,1],
  [6,5],
  [1,1],
  [3,2],
  [2,3]
]

function makeUnique(arr) {
  var uniques = [];
  var itemsFound = {};
  for(var i = 0, l = arr.length; i < l; i  ) {
      let [a,b] = arr[i];
      const hashKey = [ Math.min(a,b), Math.max(a,b)];
      var stringified = JSON.stringify(hashKey);
      if(itemsFound[stringified])  continue; 
      uniques.push(arr[i]);
      itemsFound[stringified] = true;
  }
  return uniques;
}

let ans1=makeUnique(a)
console.log(ans1);

2.among similar , one with smaller first key should stay

now you can remember in the hashmap what the value for a key was and keep updating it based on the correct candidate

let a = [
  [5, 6],
  [1,1],
  [6,5],
  [1,1],
  [3,2],
  [2,3]
]

function makeUniqueSmallerFirst(arr) {
  var items = {};
  for(var i = 0, l = arr.length; i < l; i  ) {
      let [a,b] = arr[i];
      const hashKey = [ Math.min(a,b), Math.max(a,b)];
      var stringified = JSON.stringify(hashKey);
      
      if (stringified in items) {
          let previous = items[stringified];
          if (previous[0] > arr[i][0]) {
              items[stringified] = arr[i];
          }
      } else {
          items[stringified] =  arr[i]  // I am just storing  the array because if I see a similar item next time, I can compare if that has first item smaller or not 
      }
      
  }

  return Object.values(items); // this doesn't guarantee output order though
  // if you want order as well . you can iterate over input array once more and arrange the items in the preffered order.
}

let ans2=makeUniqueSmallerFirst(a)
console.log(ans2);

CodePudding user response:

UPDATED (More simple and faster example for ES5 ):

function makeUnique(arr) {
    return new Set(a.map(
        arr => JSON.stringify(arr.sort((a, b) => a - b)))
    )
}

const m = makeUnique(a)
console.log(m) // 

OLD:

This is an example of code that makes a two-dimensional array with arrays of any length unique.

let a = [
    [5, 6],
    [1, 1],
    [6, 5],
    [1, 5],
    [3, 2],
    [2, 3],
    [6, 5, 3],
    [3, 5, 6]
]

function isUnique(uniqueArray, checkedArray) {
    let checked = [...checkedArray];
    let unique = [...uniqueArray];
    let uniqueValue = 0;
    unique.forEach(value => {
        if (checked.includes(value)) {
            checked.splice(checked.indexOf(value), 1)
        } else uniqueValue  ;
    })
    return uniqueValue > 0;
}

function makeUnique(array2d) {
    let unique = [array2d[0]]
    array2d.forEach(checkedArray => {
        if (unique.some(uniqueArray => {
                if (checkedArray.length !== uniqueArray.length) return false;
                return !isUnique(uniqueArray, checkedArray)
            }
        )) return 0;
        else unique.push(checkedArray)
    })
    return unique
}

console.log(makeUnique(a)) // [ [ 5, 6 ], [ 1, 1 ], [ 1, 5 ], [ 3, 2 ], [ 6, 5, 3 ] ]

isUnique() this function checks if the numbers in both arrays are unique, and if they are, it outputs true. We use the copy through spread operator, so that when you delete a number from an array, the array from outside is not affected.

makeUnique() function makes the array unique, in the following way: It checks if our unique two-dimensional array has at least one array that is identical to checkedArray

The first check if the arrays are of different lengths - they are unique, skip and check for uniqueness, if !isUnique gives out true, then the array is skipped by return 0

  • Related