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

#javascript #arrays

#javascript #массивы

Вопрос:

Как я могу получить уникальный массив, но игнорируя один из параметров в массиве? Я хочу проигнорировать name и сравнить другие, скажем так…

 let inventories = [
  {name: 'Polo Shirt', size: 'XL', price: 19.90, color: 'black'},
  {name: 'Polo Shirt (Stripe)', size: 'XL', price: 19.90, color: 'black'},
  {name: 'Polo Shirt (Printed)', size: 'XL', price: 19.90, color: 'black'},
  {name: 'Short Sleeve Polo Shirt', size: 'L', price: 14.90, color: 'blue'},
  {name: 'Sleeve Polo Shirt', size: 'L', price: 20.90, color: 'black'},
  {name: 'Long Sleeve Polo Shirt', size: 'L', price: 14.90, color: 'blue'},
  {name: 'Long Sleeve Polo Shirt', size: 'L', price: 14.90, color: 'blue'},
  {name: 'Long Sleeve Polo Shirt', size: 'L', price: 14.90, color: 'blue'},
];
  

Результат, который я хочу:

 [
  {name: 'Polo Shirt (Printed)', size: 'XL', price: 19.90, color: 'black'},
  {name: 'Sleeve Polo Shirt', size: 'L', price: 20.90, color: 'black'},
  {name: 'Long Sleeve Polo Shirt', size: 'L', price: 14.90, color: 'blue'},
];
  

Я знаю, что мы можем получить уникальный массив с помощью:

 inventories = inventories
  .map(JSON.stringify)
  .reverse()
  .filter(function(item, index, inventories) {
    return inventories.indexOf(item, index   1) === -1;
  

Но я не уверен, как сказать им игнорировать name параметр…

Комментарии:

1. Почему выбирается Sleeve Polo Shirt , а не Short Sleeve Polo Shirt нет?!!

2. Какое свойство мы должны проверить на наличие дубликатов?!!

3. @ZakariaAcharki неважно, какое имя выбрать, моя цель здесь — проигнорировать name параметр и найти уникальные массивы. Свойства, которые я хочу проверить, — это все остальные свойства, кроме name property

Ответ №1:

Я думаю, это самый простой вариант. Вы можете создать хэш-таблицу и сгенерировать уникальный ключ на основе свойств, отличных от name . Смотрите следующий код:

 let inventories = [
  {name: 'Polo Shirt', size: 'XL', price: 19.90, color: 'black'},
  {name: 'Polo Shirt (Stripe)', size: 'XL', price: 19.90, color: 'black'},
  {name: 'Polo Shirt (Printed)', size: 'XL', price: 19.90, color: 'black'},
  {name: 'Short Sleeve Polo Shirt', size: 'L', price: 14.90, color: 'blue'},
  {name: 'Sleeve Polo Shirt', size: 'L', price: 20.90, color: 'black'},
  {name: 'Long Sleeve Polo Shirt', size: 'L', price: 14.90, color: 'blue'},
  {name: 'Long Sleeve Polo Shirt', size: 'L', price: 14.90, color: 'blue'},
  {name: 'Long Sleeve Polo Shirt', size: 'L', price: 14.90, color: 'blue'}
]

const hash = {}

inventories.forEach(function(elem) {
  var selected =  Object.assign({}, elem);
  delete selected.name;
  const key = Object.values(selected).join('-');
  hash[key] = elem;
});
const result = Object.values(hash);

console.log(result);  
 .as-console-wrapper { max-height: 100% !important; top: 0; }  

Комментарии:

1.Это легче читать, но что, если у меня в массиве больше свойств / параметров? Нужно ли мне будет перечислять все свойства, такие как elem.x elem.y elem.z и т.д.? Есть ли способ заставить код игнорировать то, что я хочу игнорировать, вместо того, чтобы перечислять то, что я хочу?

2. Привет @pizza0502, я обновил свой код. Пожалуйста, проверьте это.

Ответ №2:

Вы могли бы использовать filter метод с Object.values параметром ... rest.

 let data = [{"name":"Polo Shirt","size":"XL","price":19.9,"color":"black"},{"name":"Polo Shirt (Stripe)","size":"XL","price":19.9,"color":"black"},{"name":"Polo Shirt (Printed)","size":"XL","price":19.9,"color":"black"},{"name":"Short Sleeve Polo Shirt","size":"L","price":14.9,"color":"blue"},{"name":"Sleeve Polo Shirt","size":"L","price":20.9,"color":"black"},{"name":"Long Sleeve Polo Shirt","size":"L","price":14.9,"color":"blue"},{"name":"Long Sleeve Polo Shirt","size":"L","price":14.9,"color":"blue"},{"name":"Long Sleeve Polo Shirt","size":"L","price":14.9,"color":"blue"}]

const uniq = data.reverse().filter(function({name, ...rest}) {
  const key = Object.values(rest).join('-');
  if(!this[key]) return this[key] = true;
  else return false;
}).reverse()

console.log(uniq)  

Ответ №3:

Вы могли бы использовать Map with .reduce и воспользоваться тем фактом, что он перезапишет любые элементы, установленные с тем же key значением, вот так:

 const inventories = [{"name":"Polo Shirt","size":"XL","price":19.9,"color":"black"},{"name":"Polo Shirt (Stripe)","size":"XL","price":19.9,"color":"black"},{"name":"Polo Shirt (Printed)","size":"XL","price":19.9,"color":"black"},{"name":"Short Sleeve Polo Shirt","size":"L","price":14.9,"color":"blue"},{"name":"Sleeve Polo Shirt","size":"L","price":20.9,"color":"black"},{"name":"Long Sleeve Polo Shirt","size":"L","price":14.9,"color":"blue"},{"name":"Long Sleeve Polo Shirt","size":"L","price":14.9,"color":"blue"},{"name":"Long Sleeve Polo Shirt","size":"L","price":14.9,"color":"blue"}];

const res = [...inventories.reduce((acc, obj) => {
  const {name, ...others} = obj;
  const unq_key = Object.values(others).join('_');
  acc.set(unq_key, obj);
  return acc;
}, new Map).values()];

console.log(res);