根据匹配的 id 计算元素 javascript

count element on the basis of matching id javascript

var data = [{
    id: '1',
    status: 'pending'
}, {
    id: '2',
    status: 'delivered'
}, {
    id: '2',
    status: 'pending'
}, {
    id: '1',
    status: 'shipped'
}, {
    id: '1',
    status: 'pending'
}, {
    id: '2',
    status: 'delivered'
}, {
    id: '2',
    status: 'shipped'
}]



output: [{
    id: 1,
    order: {
        pending: 2,
        shipped: 1
    },
    id: 2,
    order: {
        pending: 1,
        delivered: 2,
        shipped: 1
    }
}]

一种方法是使用 Array reduce 和 find。

var ret = data.reduce(function(o, v) {
  //change id to Number
  var idNum = Number(v.id);

  var ele = o.find(function(e, i) {
    return idNum === e.id;
  });
  if (!ele) {
    //ID is not there in our output, let's create it
    ele = {
      id: idNum,
      order: {}
    };
    o.push(ele);
  }
  //update order status
  //if it's empty start with zero and increase it
  ele.order[v.status] = (ele.order[v.status] || 0) + 1;
  return o;
}, []);
console.log(JSON.stringify(ret));

使用Array#reduce创建以id为键的对象,Object#values()转换

var data = [{
  id: '1',
  status: 'pending'
}, {
  id: '2',
  status: 'delivered'
}, {
  id: '2',
  status: 'pending'
}, {
  id: '1',
  status: 'shipped'
}, {
  id: '1',
  status: 'pending'
}, {
  id: '2',
  status: 'delivered'
}, {
  id: '2',
  status: 'shipped'
}]

let res = Object.values(
  data.reduce((a, c) => {
    if (!a[c.id]) {
      a[c.id] = {id: c.id, order: {pending:0, shipped:0, delivered:0}};
    }
    a[c.id].order[c.status] ++;
    return a
  }, {})
);

console.log(res)

返回数组: