Мне нужно удалить похожие дубликаты, а также настоящие дубликаты из 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] (тот, у которого больше начальное значение индекса).
Не могли бы вы помочь мне исправить это?
Вот пример того, как вы можете это сделать:
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;
}
Я надеюсь, что это помогает.
Имеет ли значение порядок uniques array?
Хорошо, спасибо, не могли бы вы сделать так, чтобы он сохранял меньшее количество двух одинаковых дубликатов. например, если у нас есть [2,3] и [3,2], он должен сохранить [2,3], потому что он ниже, ваш код в настоящее время сохраняет первый элемент двух похожих дубликатов, он не проверяет, какой из них ниже.
Есть две части
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
Извини. Я не видел «тот, у которого больше начальное значение индекса». Держись плз.