Удалить похожие дубликаты из 2D-массива в JavaScript

Мне нужно удалить похожие дубликаты, а также настоящие дубликаты из 2D-массива в 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.info(a);

У меня есть этот вывод:

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

Правильно должно быть:

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

Мой код правильно удаляет дубликаты, но мне также нужно удалить похожие дубликаты.

Например, если у меня есть [3,2] и [2,3], я должен удалить [3,2] (тот, у которого больше начальное значение индекса).

Не могли бы вы помочь мне исправить это?

Что такое двойные вопросительные знаки (??) в JavaScript?
Что такое двойные вопросительные знаки (??) в JavaScript?
Как безопасно обрабатывать неопределенные и нулевые значения в коде с помощью Nullish Coalescing
Асинхронная передача данных с помощью sendBeacon в JavaScript
Асинхронная передача данных с помощью sendBeacon в JavaScript
В современных веб-приложениях отправка данных из JavaScript на стороне клиента на сервер является распространенной задачей. Одним из популярных...
Принципы ООП в JavaScript
Принципы ООП в JavaScript
Парадигма объектно-ориентированного программирования имеет 4 основных принципа,
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Слишком много useState? Давайте useReducer!
Слишком много useState? Давайте useReducer!
Современный фронтенд похож на старую добрую веб-разработку, но с одной загвоздкой: страница в браузере так же сложна, как и бэкенд.
Типы данных JavaScript
Типы данных JavaScript
В JavaScript существует несколько типов данных, включая примитивные типы данных и ссылочные типы данных. Вот краткое объяснение различных типов данных...
1
0
87
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вот пример того, как вы можете это сделать:


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

Я надеюсь, что это помогает.

Извини. Я не видел «тот, у которого больше начальное значение индекса». Держись плз.

paransaik 11.01.2023 06:33

Имеет ли значение порядок uniques array?

paransaik 11.01.2023 06:48

Хорошо, спасибо, не могли бы вы сделать так, чтобы он сохранял меньшее количество двух одинаковых дубликатов. например, если у нас есть [2,3] и [3,2], он должен сохранить [2,3], потому что он ниже, ваш код в настоящее время сохраняет первый элемент двух похожих дубликатов, он не проверяет, какой из них ниже.

codproe 11.01.2023 07:02
Ответ принят как подходящий

Есть две части

  1. подобное следует рассматривать
  2. среди подобных должен остаться тот, у которого первый ключ меньше

1. Подобные следует учитывать

Здесь вы можете просто сделать ключ для hashmap таким образом, чтобы похожие элементы давали один и тот же ключ.

Один из способов сделать это - отсортировать элементы в кортеже, а затем сформировать ключ, так как есть только два элемента, первый будет минимальным, а второй - максимальным.

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.info(ans1);

2. Среди похожих должен остаться тот, у которого первый ключ меньше

Теперь вы можете запомнить в хэш-карте значение ключа и продолжать обновлять его на основе правильного кандидата.

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 preferred order.
}

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

ОБНОВЛЕНО (более простой и быстрый пример для ES5+):

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

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

СТАРЫЙ:

Это пример кода, который делает двумерный массив с массивами любой длины уникальными.

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.info(makeUnique(a)) // [ [ 5, 6 ], [ 1, 1 ], [ 1, 5 ], [ 3, 2 ], [ 6, 5, 3 ] ]

IsUnique() эта функция проверяет, уникальны ли числа в обоих массивах, и если да, то выводит true. Мы используем оператор копирования через распространение, чтобы при удалении числа из массива массив извне не затрагивался.

MakeUnique() функция делает массив уникальным следующим образом: Он проверяет, есть ли в нашем уникальном двумерном массиве хотя бы один массив, идентичный checkedArray

Первая проверка если массивы разной длины - они уникальны, пропускаем и проверяем на уникальность, если !isUnique выдает true, то массив пропускаем по return 0

Другие вопросы по теме