Как получить эти массивы объектов из заданного массива объектов?

#javascript

#javascript

Вопрос:

В моем входном массиве объектов у меня есть поле с именем Grade. Это параметр фильтрации

 var input = [
 {
  "Qty": "2.00",
  "Grade": "AU27",
  "Thickness": "5.00",
  "Width": "1200.00",
 },
 {
  "Qty": "7.00",
  "Grade": "AU27",
  "Thickness": "10.00",
  "Width": "1400.00",
 },
 {
  "Qty": "17.00",
  "Grade": "AU27",
  "Thickness": "5.00",
  "Width": "1700.00",
 },
 {
  "Qty": "51.00",
  "Grade": "FE500D",
  "Thickness": "10.00",
  "Width": "1100.00",
 },
 {
  "Qty": "69.00",
  "Grade": "FE500D",
  "Thickness": "12.00",
  "Width": "1500.00",
 },
 {
  "Qty": "30.00",
  "Grade": "FE500D",
  "Thickness": "8.00",
  "Width": "1800.00",
 },
 {
  "Qty": "92.00",
  "Grade": "FE500D",
  "Thickness": "10.00",
  "Width": "2200.00",
 },
 {
  "Qty": "98.00",
  "Grade": "FE600D",
  "Thickness": "11.00",
  "Width": "2400.00",
 },
 {
  "Qty": "115.00",
  "Grade": "FE600D",
  "Thickness": "17.00",
  "Width": "2600.00",
 }
];
  

Я хочу создать массив объекта с именем sumGradeArray из приведенного выше входного массива. Если мы рассмотрим общее количество разных сортов, независимо от толщины и ширины, то общее количество сортов AU27 равно
2.00 7.00 17.00 = 26.00.

Аналогично для класса FE500D общее количество 51.00 69.00 30.00 92.00 = 242,00

Аналогично для класса FE600D общее количество составляет 98,00 115,00 = 213,00

  var sumGradeArray = [
 {      
  "Grade": "AU27",
  "TotalQty": "26.00",
 },
 {      
  "Grade": "FE500D",
  "TotalQty": "242.00",
 },
 {      
  "Grade": "FE600D",
  "TotalQty": "213.00",
 },
];
  

Пожалуйста, кто-нибудь, предоставьте мне общее решение с использованием ванильного JS (без Jquery / Lodash). Я показываю здесь только 3 оценки, на самом деле входной массив объекта является ответом API. Он может иметь сотни классов

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

1. Вы не получаете шоу…. что вы пробовали до сих пор

Ответ №1:

Вы могли бы взять Map для группировки одного и того же класса и отобразить требуемый стиль.

 var input = [{ Qty: "2.00", Grade: "AU27", Thickness: "5.00", Width: "1200.00" }, { Qty: "7.00", Grade: "AU27", Thickness: "10.00", Width: "1400.00" }, { Qty: "17.00", Grade: "AU27", Thickness: "5.00", Width: "1700.00" }, { Qty: "51.00", Grade: "FE500D", Thickness: "10.00", Width: "1100.00" }, { Qty: "69.00", Grade: "FE500D", Thickness: "12.00", Width: "1500.00" }, { Qty: "30.00", Grade: "FE500D", Thickness: "8.00", Width: "1800.00" }, { Qty: "92.00", Grade: "FE500D", Thickness: "10.00", Width: "2200.00" }, { Qty: "98.00", Grade: "FE600D", Thickness: "11.00", Width: "2400.00" }, { Qty: "115.00", Grade: "FE600D", Thickness: "17.00", Width: "2600.00" }],
    result = Array.from(
        input.reduce((m, o) => m.set(o.Grade, ( (m.get(o.Grade) || 0)    o.Qty).toFixed(2)), new Map),
        ([Grade, TotalQty]) => ({ Grade, TotalQty })
    );

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

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

1. @window.document, правильно. спасибо за подсказку. пожалуйста, смотрите Редактирование.

2. @Nina Scholz Ваш ответ неверен. Я не получаю желаемый массив объектов. Сумма полностью неверна. Ответ Махира Али правильный (за исключением того, что он, вероятно, пропустил отображение результатов в 2 десятичных разрядах)

3. @RobbieCrusoe, пожалуйста, перезагрузите страницу и проверьте результат.

4. @Nina Scholz Спасибо, что ваше новое решение работает. Я принимаю ваш ответ

Ответ №2:

Вы можете использовать reduce() и findIndex() для этого.

 var input = [ { "Qty": "2.00", "Grade": "AU27", "Thickness": "5.00", "Width": "1200.00", }, { "Qty": "7.00", "Grade": "AU27", "Thickness": "10.00", "Width": "1400.00", }, { "Qty": "17.00", "Grade": "AU27", "Thickness": "5.00", "Width": "1700.00", }, { "Qty": "51.00", "Grade": "FE500D", "Thickness": "10.00", "Width": "1100.00", }, { "Qty": "69.00", "Grade": "FE500D", "Thickness": "12.00", "Width": "1500.00", }, { "Qty": "30.00", "Grade": "FE500D", "Thickness": "8.00", "Width": "1800.00", }, { "Qty": "92.00", "Grade": "FE500D", "Thickness": "10.00", "Width": "2200.00", }, { "Qty": "98.00", "Grade": "FE600D", "Thickness": "11.00", "Width": "2400.00", }, { "Qty": "115.00", "Grade": "FE600D", "Thickness": "17.00", "Width": "2600.00", } ];

const res = input.reduce((ac,{Grade,Qty}) => {
  let index = ac.findIndex(x => x.Grade === Grade);
  index === -1 ? ac.push({Grade,totalQty: Qty}) : ac[index].totalQty  =  Qty
  return ac;
},[]).map(x => ({...x,totalQty:x.totalQty.toFixed(2)}))
console.log(res)  

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

1. Пожалуйста, хотите получить ответ в 2 десятичных разрядах

2. Я тоже проголосовал за вас. Но поскольку Нина Шольц ответила первой, я отметил ее как правильную.

3. Я нажал на повышение, но да, возможно, они не позволяют мне повышать.

Ответ №3:

Почему вы хотите, чтобы ваши количества были представлены в виде строк в конечном результате, когда они на самом деле являются числами? И почему бы не структурировать ваш объект так, { [grade]: <quantity> } поскольку ваш объект теперь уникален grade , и к нему будет легче получить доступ и работать с ним?

Мой ответ предполагает, что вы согласны выполнить эти две вещи

Фрагмент кода

 var input = [
 {
  "Qty": "2.00",
  "Grade": "AU27",
  "Thickness": "5.00",
  "Width": "1200.00",
 },
 {
  "Qty": "7.00",
  "Grade": "AU27",
  "Thickness": "10.00",
  "Width": "1400.00",
 },
 {
  "Qty": "17.00",
  "Grade": "AU27",
  "Thickness": "5.00",
  "Width": "1700.00",
 },
 {
  "Qty": "51.00",
  "Grade": "FE500D",
  "Thickness": "10.00",
  "Width": "1100.00",
 },
 {
  "Qty": "69.00",
  "Grade": "FE500D",
  "Thickness": "12.00",
  "Width": "1500.00",
 },
 {
  "Qty": "30.00",
  "Grade": "FE500D",
  "Thickness": "8.00",
  "Width": "1800.00",
 },
 {
  "Qty": "92.00",
  "Grade": "FE500D",
  "Thickness": "10.00",
  "Width": "2200.00",
 },
 {
  "Qty": "98.00",
  "Grade": "FE600D",
  "Thickness": "11.00",
  "Width": "2400.00",
 },
 {
  "Qty": "115.00",
  "Grade": "FE600D",
  "Thickness": "17.00",
  "Width": "2600.00",
 }
];

const sumGradeArray = input.reduce((gradeSums, { Grade, Qty }) => 
    gradeSums[Grade] 
        ? { ...gradeSums, [Grade]: gradeSums[Grade]   Number(Qty) } 
        : { ...gradeSums, [Grade]: Number(Qty) }
    , {})
    
console.log(sumGradeArray);  

 // result:
{
    AU27: 26, 
    FE500D: 242, 
    FE600D: 213
}
  

Объяснение

 const sumGradeArray = input.reduce((gradeSums, { Grade, Qty }) => 
  

Здесь мы выполняем reduce . По ссылке есть лучшее объяснение, но, по сути, мы перебираем массив и сохраняем все, что мы возвращаем к первому параметру, в данном случае gradeSums . Второй параметр — это элемент в массиве, деструктурированный здесь для быстрого доступа к свойствам Grade и Qty .

 gradeSums[Grade] 
  

Если мы уже сохранили значение для этой оценки, то мы хотим добавить значение в текущем элементе к тому, что у нас уже есть, в результате чего получим это правдивое утверждение:

 ? { ...gradeSums, [Grade]: gradeSums[Grade]   Number(Qty) } 
  

Мы распределяем предыдущие накопленные значения, чтобы не потерять их.

 : { ...gradeSums, [Grade]: Number(Qty) }
  

Однако, если мы не видели этого до того, как создадим новую запись для количества, которое мы только что видели.

 , {})
  

Начальным значением должен быть объект, чтобы мы могли успешно его распространять.

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

1. Нежелательный результат

2. Это лучший результат. Вы не предоставили объяснения, почему вам нужна ваша структура данных.

3. Махир Али и Нина Шольц ответили в соответствии с моим требованием