Нужна помощь во вложении функций массива в JavaScript - PullRequest
0 голосов
/ 08 декабря 2018

У меня есть два массива объектов JavaScript:

const types = [
  {
    id: 1,
    name: 'Paint',
    unit: 'L',
  },
  {
    id: 2,
    name: 'Resin',
    unit: 'mL',
  },
  {
    id: 3,
    name: 'Fiberglass',
    unit: 'yd',
  }
];

const items = [
  {
    id: 1,
    type_id: 1,
    name: 'Brand x paint',

    qty: 5,
  },
  {
    id: 2,
    type_id: 1,
    name: 'Brand y paint',
    supplier: 'brand y',
    qty: 3,
  },
  {
    id: 3,
    type_id: 2,
    name: 'Brand x resin',
    qty: 5,
  },
  {
    id: 3,
    type_id: 2,
    name: 'Brand y resin',
    qty: 2,
  },
  {
    id: 3,
    type_id: 2,
    name: 'Brand z resin',
    qty: 3,
  },
  {
    id: 3,
    type_id: 2,
    name: 'Brand x fiberglass',
    qty: 7,
  },
  {
    id: 3,
    type_id: 2,
    name: 'Brand y fiberglass',
    qty: 9,
  },
];

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

const itemTypes  =  types.map( (type) => {
    type.total_qty = items
      .filter((items) => items.type_id === type.id)
      .reduce((sum, item) => sum += item.qty, 0)
  }     
)

Я просто хочу сделать вышеописанное, но если есть лучшие способы добавления свойства total_quantity рядом с типом, тогда я открытк предложениям.Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 08 декабря 2018

Проблема в том, что вы используете map без return в своем обратном вызове, а вместо mutate указанный массив.Так что map возвращает undefined значений, в то время как ваш массив types был обновлен (но не выводится).

Вот немного более эффективный метод, использующий Map, чтобы избежать вложенностиитераций.Таким образом, он работает в O (n) вместо O (n²) сложности времени.

Он также позволяет избежать изменения оригинальных объектов type, но создает новые объекты (с дополнительным свойством) во вновь созданном массиве:

const types = [ { id: 1, name: 'Paint', unit: 'L', }, { id: 2, name: 'Resin', unit: 'mL', }, { id: 3, name: 'Fiberglass', unit: 'yd', } ]; 
const items = [ { id: 1, type_id: 1, name: 'Brand x paint', qty: 5, }, { id: 2, type_id: 1, name: 'Brand y paint', supplier: 'brand y', qty: 3, }, { id: 3, type_id: 2, name: 'Brand x resin', qty: 5, }, { id: 3, type_id: 2, name: 'Brand y resin', qty: 2, }, { id: 3, type_id: 2, name: 'Brand z resin', qty: 3, }, { id: 3, type_id: 2, name: 'Brand x fiberglass', qty: 7, }, { id: 3, type_id: 2, name: 'Brand y fiberglass', qty: 9, }, ];

// Map keyed by type_id and with the extended type object as value 
// (initialised as 0)
const map = new Map(types.map( type => [type.id, {...type, total_qty: 0 }] ));
// Add the quantities from the items to the appropriate map-value
items.forEach(item => map.get(item.type_id).total_qty += item.qty);
// Extract the map values
const itemTypes = Array.from(map.values());
console.log(itemTypes); 
0 голосов
/ 08 декабря 2018

Более эффективной альтернативой было бы создание объекта поиска с количествами по id:

const types = [ { id: 1, unit: 'L', name: 'Paint', }, { id: 2, unit: 'mL', name: 'Resin', }, { id: 3, unit: 'yd', name: 'Fiberglass', } ]; 

const items = [ { id: 1, type_id: 1, qty: 5, name: 'Brand x paint', }, { id: 2, type_id: 1, qty: 3, name: 'Brand y paint', supplier: 'brand y', }, { id: 3, type_id: 2, qty: 5, name: 'Brand x resin', }, { id: 3, type_id: 2, qty: 2, name: 'Brand y resin', }, { id: 3, type_id: 2, qty: 3, name: 'Brand z resin', }, { id: 3, type_id: 2, qty: 7, name: 'Brand x fiberglass', }, { id: 3, type_id: 2, qty: 9, name: 'Brand y fiberglass', }, ];

const qtys = items.reduce((obj, item) => 
                   (obj[item.type_id] = (obj[item.type_id] || 0) + item.qty, obj), {})

const itemTypes = types.map(type => ({ ...type, total_qty: qtys[type.id] }))

console.log( JSON.stringify( itemTypes ).replace(/},/g, '},\n ') )
console.log( qtys )

Для получения информации о синтаксисе распространения в литералах объекта: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals

0 голосов
/ 08 декабря 2018

Вам не хватает начального значения для аккумулятора в reduce.

const itemsType  =  types.map( (type) => {
     const temp = items;
     type.total_qty = temp
         .filter( item => item.type_id === type.id)
         .reduce( (acc, item) => acc + item.qty, 0); // value missing here
  }     
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...