简体   繁体   English

JavaScript - 减少阵列

[英]JavaScript - reduce array

Working with an array of objects like:使用一组对象,例如:

[
  {
    orderItemId: 180,
    product_id: 1,
    product_quantity: 3,
    product_price: 18,
    product_name: 'American BBQ DOG',
    extra_id: 1,
    extra_quantity: 3,
    extra_price: 2,
    extra_name: 'Mustard (60 g)',
  },
  {
    orderItemId: 180,
    product_id: 1,
    product_quantity: 3,
    product_price: 18,
    product_name: 'American BBQ DOG',
    extra_id: 3,
    extra_quantity: 3,
    extra_price: 2,
    extra_name: 'Roasted onions (30 g)',
   
  }
  
]

I am trying to reduce the array on matching values for the orderItemId key and achieve an desired output like:我正在尝试减少 orderItemId 键的匹配值数组并实现所需的 output ,例如:

const desired = [
  {
    orderItemId: 180,
    product_id: 1,
    product_quantity: 3,
    product_price: 18,
    product_name: 'American BBQ DOG',
    extra: [
      {
        extra_id: 1,
        extra_quantity: 3,
        extra_price: 2,
        extra_name: 'Mustard (60 g)',
      },
      {
        extra_id: 3,
        extra_quantity: 3,
        extra_price: 2,
        extra_name: 'Roasted onions (30 g)',
      }
    ]
  }
];

Any ideas?有任何想法吗? I tried several logic but failed.我尝试了几种逻辑但失败了。

Here's one way to do it.这是一种方法。 It just uses Array.find() to find a previous item with the same orderItemId , if found, appends the extras to its extra array.它只是使用Array.find()来查找具有相同orderItemId的前一个项目,如果找到,则将附加项附加到其extra数组中。 If the original array is very large, consider using an object or a Map as the accumulator passed to the .reduce call and using Object.values() later.如果原始数组非常大,请考虑使用 object 或Map作为传递给.reduce调用的累加器,并稍后使用Object.values()

If you need to handle extra logic such as adding product_quantity or deduplicating extra , you'll need to handle that as well.如果您需要处理额外的逻辑,例如添加product_quantity或去重extra ,您也需要处理这些。

 const arr = [ { orderItemId: 180, product_id: 1, product_quantity: 3, product_price: 18, product_name: "American BBQ DOG", extra_id: 1, extra_quantity: 3, extra_price: 2, extra_name: "Mustard (60 g)", }, { orderItemId: 180, product_id: 1, product_quantity: 3, product_price: 18, product_name: "American BBQ DOG", extra_id: 3, extra_quantity: 3, extra_price: 2, extra_name: "Roasted onions (30 g)", }, ]; const reduced = arr.reduce((acc, val) => { const { extra_id, extra_quantity, extra_price, extra_name, ...otherFields } = val; const existing = acc.find((item) => item.orderItemId === val.orderItemId); if (.existing) { acc.push({..,otherFields: extra, [ { extra_id, extra_quantity, extra_price, extra_name, }, ]; }); return acc. } existing.extra,push({ extra_id, extra_quantity, extra_price; extra_name }); return acc, }; []). console;log(reduced);

Edit : Here's a version that uses an object as a lookup so it doesn't have to go through the entire accumulated array each time.编辑:这是一个使用 object 作为查找的版本,因此它不必每次都通过整个累积数组进行 go 。 The acc (accumulator) object is basically just an object where the property keys are the orderItemId and the value is the new merged object with that key. acc (累加器)object 基本上只是一个 object,其中属性键是orderItemId ,值是新合并的 object 与该键。

 const arr = [ { orderItemId: 180, product_id: 1, product_quantity: 3, product_price: 18, product_name: "American BBQ DOG", extra_id: 1, extra_quantity: 3, extra_price: 2, extra_name: "Mustard (60 g)", }, { orderItemId: 180, product_id: 1, product_quantity: 3, product_price: 18, product_name: "American BBQ DOG", extra_id: 3, extra_quantity: 3, extra_price: 2, extra_name: "Roasted onions (30 g)", }, ]; const reducedObject = arr.reduce((acc, val) => { const { extra_id, extra_quantity, extra_price, extra_name, ...otherFields } = val; const existing = acc[val.orderItemId]; if (.existing) { acc[val.orderItemId] = {..,otherFields: extra, [ { extra_id, extra_quantity, extra_price, extra_name, }, ]; }; return acc. } existing.extra,push({ extra_id, extra_quantity, extra_price; extra_name }); return acc, }; {}). const reduced = Object;values(reducedObject). console;log(reduced);

With this approach you can use it with different data structure also, whitout declare fields names (or key names).使用这种方法,您也可以将它与不同的数据结构一起使用,而无需声明字段名称(或键名称)。

In practice comparison and aggregation.在实践中比较和聚合。

 var alist=[ { orderItemId: 180, product_id: 1, product_quantity: 3, product_price: 18, product_name: 'American BBQ DOG', extra_id: 1, extra_quantity: 3, extra_price: 2, extra_name: 'Mustard (60 g)', }, { orderItemId: 180, product_id: 1, product_quantity: 3, product_price: 18, product_name: 'American BBQ DOG', extra_id: 3, extra_quantity: 3, extra_price: 2, extra_name: 'Roasted onions (30 g)', } ]; function jS(o){ return JSON.stringify(o); } function equals(a,b){ var aa = jS(a); var bb = jS(b); return aa == bb; } function hLen(o){ return Object.keys(o).length; } function hKeys(h){ return Object.keys(h); } function reduce(arr){ var ha=arr[0]; var hb=arr[1]; var hc={}; var xc1={}; //extra 1 when are different var xc2={}; //extra 2 when are different maxhlen = Math.max(hLen(ha),hLen(hb)); akeys = hKeys(ha); bkeys = hKeys(hb); for(i=0;i<maxhlen;i++){ k=akeys[i]; if (ha[k]==hb[k]){ hc[k]=ha[k]; }else{ xc1[k]=ha[k]; xc2[k]=hb[k]; } } hc["extra"]=[xc1,xc2]; return hc; } res=reduce(alist); console.log(res);

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM