Объединить объект, сохраняя его значение, используя дополнение в JavaScript - PullRequest
1 голос
/ 25 сентября 2019

У меня есть массив объектов js, структурированный как указано ниже,

items= [
    {
      discount: 27.6,
      name: 'Floy Vandervort',
      price: 230,
      quantity: 3,
      taxable: 662.4
    },
    {
      discount: 122.88,
      name: 'Adriel Abshire II',
      price: 256,
      quantity: 6,
      taxable: 1413.12
    },
    {
      discount: 159.66,
      name: 'Tabitha Stroman',
      price: 887,
      quantity: 2,
      taxable: 1614.34
    },
    {
      discount: 27.6,
      name: 'Floy Vandervort',
      price: 230,
      quantity: 3,
      taxable: 662.4
    },
    {
      discount: 122.88,
      name: 'Adriel Abshire II',
      price: 256,
      quantity: 6,
      taxable: 1413.12
    },
    {
      discount: 159.66,
      name: 'Tabitha Stroman',
      price: 887,
      quantity: 2,
      taxable: 1614.34
    },
    {
      discount: 27.6,
      name: 'Floy Vandervort',
      price: 230,
      quantity: 3,
      taxable: 662.4
    },
    {
      discount: 122.88,
      name: 'Adriel Abshire II',
      price: 256,
      quantity: 6,
      taxable: 1413.12
    },
    {
      discount: 159.66,
      name: 'Tabitha Stroman',
      price: 887,
      quantity: 2,
      taxable: 1614.34
    }
  ]

Я хочу избежать дублирования объектов на основе свойства name.Поэтому я решил объединить их, сохранив его оценку, как показано ниже,

Вариант использования

рассмотреть свойство name, здесь в массиве выше Флой Вандерворт повторяется 3 раза.Чтобы преобразовать его в один объект, объедините их в один объект, сохранив значение путем сложения.Итак, свойства discount, quantity и taxable должны быть объединены путем добавления, за исключением свойства price.

Я ищу оптимальное решение, которого я добился, используя итерации по исходному массивуи отправка объединенного объекта в другой массив.Я хочу устранить сложность, это возможно?если да, то как?Вот функция, которую я использую

function(items) {
  let filtered = [];
  items.forEach((item) => {
    if (!isContains(filtered, item)) {
      filtered.push(item);
    } else {
      index = filtered.findIndex((x) => x.name === item.name);
      filtered[index].discount += item.discount;
      filtered[index].quantity += item.quantity;
      filtered[index].taxable += item.taxable;
    }
  });

  return filtered;
}

function isContains(items, ob) {
  items.forEach((item) => {
    if (item.name === ob.name) {
      return true;
    }
  });
  return false;
}

Ответы [ 3 ]

1 голос
/ 25 сентября 2019

Возврат в обратном вызове forEach не имеет никакого эффекта - isContains всегда будет возвращать false.Вместо этого лучше использовать объект или карту, проиндексированные по имени, чтобы уменьшить вычислительную сложность на порядок - тогда вы можете получить значения этого объекта, чтобы получить нужный массив:

const items=[{discount:27.6,name:"Floy Vandervort",price:230,quantity:3,taxable:662.4},{discount:122.88,name:"Adriel Abshire II",price:256,quantity:6,taxable:1413.12},{discount:159.66,name:"Tabitha Stroman",price:887,quantity:2,taxable:1614.34},{discount:27.6,name:"Floy Vandervort",price:230,quantity:3,taxable:662.4},{discount:122.88,name:"Adriel Abshire II",price:256,quantity:6,taxable:1413.12},{discount:159.66,name:"Tabitha Stroman",price:887,quantity:2,taxable:1614.34},{discount:27.6,name:"Floy Vandervort",price:230,quantity:3,taxable:662.4},{discount:122.88,name:"Adriel Abshire II",price:256,quantity:6,taxable:1413.12},{discount:159.66,name:"Tabitha Stroman",price:887,quantity:2,taxable:1614.34}];

function squish(items) {
  const squishedItemsByName = items.reduce((a, { name, ...props }) => {
    if (!a[name]) {
      a[name] = { name };
    }
    Object.entries(props).forEach(([prop, val]) => {
      a[name][prop] = (a[name][prop] || 0) + val;
    });
    return a;
  }, {});
  return Object.values(squishedItemsByName);
}

console.log(squish(items));
0 голосов
/ 25 сентября 2019

Один из многих способов сделать это может быть следующим:

const uniqueItems = Object.values(
    items.reduce((hashMap, item) => { 
        if (!hashMap[item.name]) {
            hashMap[item.name] = { ...item };
        } else {
            // You should use a safest way to add 
            hashMap[item.name].discount += item.discount;
            hashMap[item.name].price += item.price;
            hashMap[item.name].quantity += item.quantity;
            hashMap[item.name].taxable += item.taxable;
        }

        return hashMap;
    }, {})
)
0 голосов
/ 25 сентября 2019

Попробуйте

let h = {};
items.forEach(x=> h[x.name]= !h[x.name] ? x : {
      discount: h[x.name].discount+x.discount,
      name: x.name,
      price: x.price,
      quantity: h[x.name].quantity+x.quantity,
      taxable: h[x.name].taxable+x.taxable
    });

let result = Object.keys(h).map(k=> h[k]);

items= [
    {
      discount: 27.6,
      name: 'Floy Vandervort',
      price: 230,
      quantity: 3,
      taxable: 662.4
    },
    {
      discount: 122.88,
      name: 'Adriel Abshire II',
      price: 256,
      quantity: 6,
      taxable: 1413.12
    },
    {
      discount: 159.66,
      name: 'Tabitha Stroman',
      price: 887,
      quantity: 2,
      taxable: 1614.34
    },
    {
      discount: 27.6,
      name: 'Floy Vandervort',
      price: 230,
      quantity: 3,
      taxable: 662.4
    },
    {
      discount: 122.88,
      name: 'Adriel Abshire II',
      price: 256,
      quantity: 6,
      taxable: 1413.12
    },
    {
      discount: 159.66,
      name: 'Tabitha Stroman',
      price: 887,
      quantity: 2,
      taxable: 1614.34
    },
    {
      discount: 27.6,
      name: 'Floy Vandervort',
      price: 230,
      quantity: 3,
      taxable: 662.4
    },
    {
      discount: 122.88,
      name: 'Adriel Abshire II',
      price: 256,
      quantity: 6,
      taxable: 1413.12
    },
    {
      discount: 159.66,
      name: 'Tabitha Stroman',
      price: 887,
      quantity: 2,
      taxable: 1614.34
    }
  ]

let h = {};
items.forEach(x=> h[x.name]= !h[x.name] ? x : {
      discount: h[x.name].discount+x.discount,
      name: x.name,
      price: x.price,
      quantity: h[x.name].quantity+x.quantity,
      taxable: h[x.name].taxable+x.taxable
    });
    
let result = Object.keys(h).map(k=> h[k]);

console.log(result);
...