如何从给定的对象数组中获取这些对象数组?

时间:2019-04-21 17:43:16

标签: 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",
 },
];

请有人为我提供使用Vanilla JS(没有Jquery / Lodash)的通用解决方案。我在这里仅显示3个等级,实际上对象的输入数组是API响应。它可以有数百个等级

3 个答案:

答案 0 :(得分:2)

您可以使用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 :(得分:1)

您可以为此使用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)

答案 2 :(得分:1)

为什么当数量实际上是数字时,为什么要在最终结果中将数量表示为字符串?又为什么不将您的对象构造为List<Product> foodList = [ Product('Cliff Bar', 'assets/cliff bar.png') Product('Coffee', 'assets/coffee.png'), ]; ,因为您的对象现在在{ [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
}

在这里,我们执行reduce。链接上有一个更好的解释,但是本质上我们是遍历数组,并保存返回第一个参数的任何内容,在这种情况下为const sumGradeArray = input.reduce((gradeSums, { Grade, Qty }) => 。第二个参数是数组destructured中的一项,此处用于快速访问属性gradeSumsGrade

Qty

如果我们已经为该年级保存了一个值,那么我们想将当前项目中的值添加到我们已有的值中,从而得到真实的陈述:

gradeSums[Grade] 

我们分散以前的累积值,以免丢失它们。

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

但是,如果在我们为刚刚看到的数量创建新条目之前还没有看到它。

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

初始值应该是一个对象,以便我们可以成功地传播它。