计算嵌套对象数组中的唯一元素

时间:2020-10-06 21:49:10

标签: javascript arrays

我需要找到一种快速有效的方法,以按生产日期和重复的总次数来计算此阵列中不同skus的数量:-

var testArray = [
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 cocobear | sand | yrs 1-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 misha | mustard | mth 6-12"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 0-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 0-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 0-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 0-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 0-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 3-6"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 3-6"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 3-6"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 gloves | grey-marle"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 gloves | grey-marle"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 madison | grey"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 madison | grey"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 madison | grey"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 madison | grey"}}
];


output.inspect(testArray);

预期输出将是这样的另一个数组:-

resultArray = [
    {"production date": "2020-09-22",
    "skus": 4,
    "items": 10},
    {"production date": "2020-10-06",
    "skus": 2,
    "items": 6}    
];

output.inspect(resultArray);

由于testArray中嵌套的对象数组,我很挣扎。

请问有什么想法吗?

谢谢

乔纳森

5 个答案:

答案 0 :(得分:1)

不确定这是否是解决此问题的最佳代码段,顺便说一句,它可以解决问题:)

  1. 我们映射到数组以访问嵌套对象:
const inspect = input => {
      const sortedData = testArray
            .map(item => item.fields)
};
  1. 然后我们可以将其简化为一个对象,其中每个键都是一个日期,并且相关值是该日期的“ skuts”数组。
const inspect = input => {
      const sortedData = testArray
            .map(item => item.fields)
            .reduce((a, c) => {
                  const productionDate = c["production date"];
                  return {
                        ...a,
                        [productionDate]: (a[productionDate] || []).concat(c.sku)
                  }
      }, {})
};
  1. 然后我们可以将其总结为一个数组,我使用Set来标识数组中不同“ skut”的数量。并且我们已经有了日期和该日期的“ skuts”总数(数组长度)。
// Final result
const inspect = input => {
      const sortedData = testArray
            .map(item => item.fields)
            .reduce((a, c) => {
                  const productionDate = c["production date"];
                  return {
                        ...a,
                        [productionDate]: (a[productionDate] || []).concat(c.sku)
                  }
      }, {})

      return Object.entries(sortedData).map(([k, v]) => ({
            "production date": k,
            items: v.length,
            skus: new Set(v).size
      }))
};
  1. 最后,您可以在数据上使用该功能:
inspect(testArray);

请注意,检查为0,我假设您的数据将始终具有正确的格式。

我还假定如果内容不同,则两个“ skut”也将不同。

答案 1 :(得分:1)

我的方式...

const result =
  testArray.reduce((a,{fields},i,t)=>
    {
    if (!a.some(x=>x['production date']===fields['production date'])) 
      {
      let prods = t.filter(x=>x.fields['production date']===fields['production date'])
                    .map(m=>m.fields.sku)
        , skus = prods.filter((v,i,t)=>i==t.lastIndexOf(v))
        ;
      a.push( {'production date': fields['production date'], skus:skus.length, items:prods.length })
      }
    return a  
    },[])

完整代码:

const testArray = 
  [ { fields: { 'production date': '2020-09-22', sku: '22-09-2020 cocobear | sand | yrs 1-3'  }} 
  , { fields: { 'production date': '2020-09-22', sku: '22-09-2020 misha | mustard | mth 6-12' }} 
  , { fields: { 'production date': '2020-09-22', sku: '22-09-2020 taylor | moon | mth 0-3'    }} 
  , { fields: { 'production date': '2020-09-22', sku: '22-09-2020 taylor | moon | mth 0-3'    }} 
  , { fields: { 'production date': '2020-09-22', sku: '22-09-2020 taylor | moon | mth 0-3'    }} 
  , { fields: { 'production date': '2020-09-22', sku: '22-09-2020 taylor | moon | mth 0-3'    }} 
  , { fields: { 'production date': '2020-09-22', sku: '22-09-2020 taylor | moon | mth 0-3'    }} 
  , { fields: { 'production date': '2020-09-22', sku: '22-09-2020 taylor | moon | mth 3-6'    }} 
  , { fields: { 'production date': '2020-09-22', sku: '22-09-2020 taylor | moon | mth 3-6'    }} 
  , { fields: { 'production date': '2020-09-22', sku: '22-09-2020 taylor | moon | mth 3-6'    }} 
  , { fields: { 'production date': '2020-10-06', sku: '06-10-2020 gloves | grey-marle'        }} 
  , { fields: { 'production date': '2020-10-06', sku: '06-10-2020 gloves | grey-marle'        }} 
  , { fields: { 'production date': '2020-10-06', sku: '06-10-2020 madison | grey'             }} 
  , { fields: { 'production date': '2020-10-06', sku: '06-10-2020 madison | grey'             }} 
  , { fields: { 'production date': '2020-10-06', sku: '06-10-2020 madison | grey'             }} 
  , { fields: { 'production date': '2020-10-06', sku: '06-10-2020 madison | grey'             }} 
  ]
const result =
  testArray.reduce((a,{fields},i,t)=>
    {
    if (!a.some(x=>x['production date']===fields['production date'])) 
      {
      let prods = t.filter(x=>x.fields['production date']===fields['production date'])
                    .map(m=>m.fields.sku)
        , skus = prods.filter((v,i,t)=>i==t.lastIndexOf(v))
        ;
      a.push( {'production date': fields['production date'], skus:skus.length, items:prods.length })
      }
    return a  
    },[])

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

答案 2 :(得分:0)

这是一个可行的命题。

$ python3 --version

如果需要,您可以循环显示结果以删除set属性

答案 3 :(得分:0)

大多数以前的答案似乎对IMO来说有点太难了。 我们可以使用Set类和一个我认为简单的reduce函数

const testArray = [
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 cocobear | sand | yrs 1-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 misha | mustard | mth 6-12"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 0-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 0-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 0-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 0-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 0-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 3-6"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 3-6"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 3-6"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 gloves | grey-marle"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 gloves | grey-marle"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 madison | grey"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 madison | grey"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 madison | grey"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 madison | grey"}}
];

// --- start here ---
let reduced = testArray
  .reduce((acc, cur) => {
    
    // use the production date as map key. this alow to easely groupby
    let curKey = cur.fields["production date"];
    if (! acc.hasOwnProperty(curKey)) {
      acc[curKey] = {
        // use a Set to maintain an array of uniq skus
        skus: new Set(),
        items: 0
      }
    }

    acc[curKey].skus.add(cur.fields.sku);
    acc[curKey].items++;

    return acc;
  }, {});

// final itaration to retrieve the size of each Set
Object.keys(reduced).map(function(key, index) {
  reduced[key].skus = reduced[key].skus.size
});

console.log(reduced);

答案 4 :(得分:0)

var testArray = [
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 cocobear | sand | yrs 1-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 misha | mustard | mth 6-12"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 0-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 0-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 0-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 0-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 0-3"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 3-6"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 3-6"}},
{fields: {"production date": "2020-09-22", "sku": "22-09-2020 taylor | moon | mth 3-6"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 gloves | grey-marle"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 gloves | grey-marle"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 madison | grey"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 madison | grey"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 madison | grey"}},
{fields: {"production date": "2020-10-06", "sku": "06-10-2020 madison | grey"}}
];

const prodDate = {};
testArray.forEach(element => {
  //check each element in the array by their sku string to see if it is already used
  if (prodDate[element.fields["production date"]]) {
    //check that if the sku is the same and add to total
    if (!prodDate[element.fields["production date"]].actualSkus[element.fields.sku]){
        prodDate[element.fields["production date"]].actualSkus[element.fields.sku] = true
        prodDate[element.fields["production date"]].skus++;
    } 
    //this is add it regardless because every item is added
      prodDate[element.fields["production date"]].items++;
    
    
    //date is not used, format the result array
  } else {
    prodDate[element.fields["production date"]] = {
        "actualSkus":{ 
          //keeping each sku to compare it in each loop
          [element.fields.sku]: true
        },
        "skus": 1,
        "items": 1
    }
  }
});
//you can keep the next 2 lines for debugging
//Object.keys(prodDate).forEach(key => {delete prodDate[key].actualSkus });
//console.log(JSON.stringify(prodDate,0,2));

//create the result desired
const resultArray = [];
Object.keys(prodDate).forEach(key => {
  resultArray.push({"production date": key, "skus": prodDate[key].skus, "items": prodDate[key].items });
});
console.log(JSON.stringify(resultArray, 0, 2));