Как удалить дубликаты вложенных объектов, сравнивая их значения - PullRequest
0 голосов
/ 04 апреля 2019

Я хотел знать, как удалить дубликаты вложенных объектов, сравнивая их значения.

 const values = [ 
    { i: 2, j: 4, l: 36 },
    { i: 4, j: 2, l: 36 },
    { i: 0, j: 2, l: 28 },
    { i: 0, j: 4, l: 28 },
    { i: 1, j: 2, l: 28 },
    { i: 1, j: 4, l: 28 },
    { i: 2, j: 1, l: 28 },
    { i: 2, j: 3, l: 28 },
    { i: 2, j: 5, l: 28 },
    { i: 3, j: 2, l: 28 },
    { i: 3, j: 4, l: 28 },
    { i: 4, j: 1, l: 28 },
    { i: 4, j: 3, l: 28 },
    { i: 4, j: 5, l: 28 },
    { i: 5, j: 2, l: 28 },
    { i: 5, j: 4, l: 28 },
    { i: 0, j: 1, l: 20 },
    { i: 0, j: 3, l: 20 },
    { i: 0, j: 5, l: 20 },
    { i: 1, j: 3, l: 20 },
    { i: 1, j: 5, l: 20 },
    { i: 3, j: 1, l: 20 },
    { i: 3, j: 5, l: 20 },
    { i: 5, j: 1, l: 20 },
    { i: 5, j: 3, l: 20 } 
 ];

В этом случае я хочу удалить вторые дубликаты объектов (которые удовлетворяют ниже условий) и пусть первый:

 value[i].i === value[j].j && value[i].j === value[i].i && value[i].l === 
 value[j].l

Требуется результат:

 const result = [
    { i: 2, j: 4, l: 36 },
    { i: 0, j: 2, l: 28 },
    { i: 0, j: 4, l: 28 },
    { i: 1, j: 2, l: 28 },
    { i: 1, j: 4, l: 28 },
    { i: 2, j: 3, l: 28 },
    { i: 2, j: 5, l: 28 },
    { i: 3, j: 4, l: 28 },
    { i: 4, j: 5, l: 28 },
    { i: 0, j: 1, l: 20 },
    { i: 0, j: 3, l: 20 },
    { i: 0, j: 5, l: 20 },
    { i: 1, j: 3, l: 20 },
    { i: 1, j: 5, l: 20 },
    { i: 3, j: 5, l: 20 }
];

Заранее спасибо.

Ответы [ 3 ]

4 голосов
/ 04 апреля 2019

Вы можете взять значения как объединенный ключ и проверить с помощью Set для фильтрации.

var values = [{ i: 2, j: 4, l: 36 }, { i: 4, j: 2, l: 36 }, { i: 0, j: 2, l: 28 }, { i: 0, j: 4, l: 28 }, { i: 1, j: 2, l: 28 }, { i: 1, j: 4, l: 28 }, { i: 2, j: 1, l: 28 }, { i: 2, j: 3, l: 28 }, { i: 2, j: 5, l: 28 }, { i: 3, j: 2, l: 28 }, { i: 3, j: 4, l: 28 }, { i: 4, j: 1, l: 28 }, { i: 4, j: 3, l: 28 }, { i: 4, j: 5, l: 28 }, { i: 5, j: 2, l: 28 }, { i: 5, j: 4, l: 28 }, { i: 0, j: 1, l: 20 }, { i: 0, j: 3, l: 20 }, { i: 0, j: 5, l: 20 }, { i: 1, j: 3, l: 20 }, { i: 1, j: 5, l: 20 }, { i: 3, j: 1, l: 20 }, { i: 3, j: 5, l: 20 }, { i: 5, j: 1, l: 20 }, { i: 5, j: 3, l: 20 }],
    s = new Set,
    filtered = values.filter(o => {
        var key1 = ['i', 'j', 'l'].map(k => o[k]).join('|'),
            key2 = ['j', 'i', 'l'].map(k => o[k]).join('|');
        return !s.has(key1) && !s.has(key2) && s.add(key1) && s.add(key2);
    });
    
console.log(values.length, filtered.length);
console.log(filtered);
.as-console-wrapper { max-height: 100% !important; top: 0; }
2 голосов
/ 04 апреля 2019

Чтобы обработать условие с помощью замены ключа, где

value[i].i === value[j].j && value[i].j === value[i].i

вы можете создать две функции, которые вычисляют значение, которое вы проверяете на равенство.Один без свопа и один с.Вы можете добавить оригинал в набор и затем в тесте фильтра, если существует измененная версия.

Например:

const values = [ 
  { i: 2, j: 4, l: 36 },
  { i: 4, j: 2, l: 36 },
  { i: 0, j: 2, l: 28 },
  { i: 0, j: 4, l: 28 },
  { i: 1, j: 2, l: 28 },
  { i: 1, j: 4, l: 28 },
  { i: 2, j: 1, l: 28 },
  { i: 2, j: 3, l: 28 },
  { i: 2, j: 5, l: 28 },
  { i: 3, j: 2, l: 28 },
  { i: 3, j: 4, l: 28 },
  { i: 4, j: 1, l: 28 },
  { i: 4, j: 3, l: 28 },
  { i: 4, j: 5, l: 28 },
  { i: 5, j: 2, l: 28 },
  { i: 5, j: 4, l: 28 },
  { i: 0, j: 1, l: 20 },
  { i: 0, j: 3, l: 20 },
  { i: 0, j: 5, l: 20 },
  { i: 1, j: 3, l: 20 },
  { i: 1, j: 5, l: 20 },
  { i: 3, j: 1, l: 20 },
  { i: 3, j: 5, l: 20 },
  { i: 5, j: 1, l: 20 },
  { i: 5, j: 3, l: 20 } 
];



const makeKey = (a) => `${a.i}_${a.j}_${a.l}`  // original key
const makeKey_test = (a) => `${a.j}_${a.i}_${a.l}` // considered a dupe

let found = new Set()
let filtered = values.filter(item => {
  if (found.has(makeKey_test(item))) return false
  found.add(makeKey(item))
  return true
})
console.log(filtered)
console.log("length:", filtered.length)

Это позволит вам проверить, содержит ли набор версию с замененными ключами, но не найдет «настоящих» дупликов с теми же i и j

0 голосов
/ 04 апреля 2019

const values = [ 
    { i: 2, j: 4, l: 36 },
    { i: 4, j: 2, l: 36 },
    { i: 0, j: 2, l: 28 },
    { i: 0, j: 4, l: 28 },
    { i: 1, j: 2, l: 28 },
    { i: 1, j: 4, l: 28 },
    { i: 2, j: 1, l: 28 },
    { i: 2, j: 3, l: 28 },
    { i: 2, j: 5, l: 28 },
    { i: 3, j: 2, l: 28 },
    { i: 3, j: 4, l: 28 },
    { i: 4, j: 1, l: 28 },
    { i: 4, j: 3, l: 28 },
    { i: 4, j: 5, l: 28 },
    { i: 0, j: 3, l: 20 },
    { i: 5, j: 2, l: 28 },
    { i: 3, j: 1, l: 20 },
    { i: 5, j: 4, l: 28 },
    { i: 0, j: 1, l: 20 },
    { i: 0, j: 3, l: 20 },
    { i: 0, j: 5, l: 20 },
    { i: 1, j: 3, l: 20 },
    { i: 1, j: 5, l: 20 },
    { i: 3, j: 1, l: 20 },
    
    { i: 3, j: 1, l: 20 },
    { i: 3, j: 5, l: 20 },
    { i: 5, j: 1, l: 20 },
    { i: 5, j: 3, l: 20 } 
 ];
 
 let objData = values; 
 
values.sort(function(a, b){ return a['i'] - b['i'] || a['j'] - b['j'] || a['l'] - b['l'] ;  });

console.log(values);
let uniqueData = [], currentObj = {}, add;
currentObj = values[0];
uniqueData.push(currentObj);
for(let i = 1; i < values.length; i++){
   add = false;
   for(let j in values[i]){
      if(values[i][j] != currentObj[j]){
        add = true;
        break;
      }
   }
   if(add){
      currentObj = values[i];
      uniqueData.push(currentObj);
   }
}
console.log(uniqueData);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...