在嵌套数组中分组、过滤和计数

group, filter and count in nested array

感谢您在我最近的帖子中提供的所有帮助!这次我得到了一个嵌套数组,我想对它们进行分组和计数。我的数组如下所示:

var arr = [
  {
    "account": {
      "id": 123,
      "name": "worker"
    },
    "fromCountry": "TE",
    "status": "created"
  },
  {
    "account": {
      "id": 3,
      "name": "worker"
    },
    "fromCountry": "TE",
    "status": "pending"
  },
  {
    "account": {
      "id": 123,
      "name": "worker"
    },
    "fromCountry": "TE",
    "status": "created"
  },
  {
    "account": {
      "id": 1,
      "name": "CEO"
    },
    "fromCountry": "FE",
    "status": "done"
  },
  {
    "account": {
      "id": 1123,
      "name": "worker"
    },
    "fromCountry": "FE",
    "status": "created"
  }
]

我想按国家/地区对它们进行分组,计算国家/地区并在子项中保存名称 typs 并计算它们。所以它必须看起来像这样:

[
  {
    name: "TE",
    value: 3,
    child: [
      {
        name: "worker",
        count: 2
      },
      {
        name: "CEO",
        count: 1
      }
    ]
  },
  {
    name: "FE",
    value: 2,
    child: [
      {
        name: "worker",
        count: 1
      },
      {
        name: "CEO",
        value: 1
      }
    ]
  }
]

(注意:我不想使用额外的 javascript 库)

你能帮帮我吗?

您可以使用reduce将数组分组到一个对象中。使用 Object.values 将对象转换为数组。使用 map 遍历数组并将子 属性 形成一个数组。

let arr = [{fromCountry:"TE",account:{name: "worker", id: 123},status:"created"},{fromCountry:"TE",account:{name: "worker", id: 3},status:"pending"},{fromCountry:"TE",account:{name: "worker", id: 123},status:"created"}, {fromCountry:"FE",account:{name: "CEO", id: 1},status:"done"}, {fromCountry:"FE",account:{name: "worker", id: 1123},status:"created"}];
 

let result = Object.values(arr.reduce((c, v) => {
  let f = v.fromCountry;
  c[f] = c[f] || {name: f,value: 0,child: {}};
  c[f].child[v.account.id] = c[f].child[v.account.id] || {name: v.account.name,count: 0}
  c[f].value++;
  c[f].child[v.account.id].count++;
  return c;
}, {})).map(o => {
  o.child = Object.values(o.child);
  return o;
});

console.log(result);

除了分组之外的关键问题就在这里,如何获得嵌套属性。该分组值由一个辅助函数获取,该辅助函数检查给定的键是否为数组。如果是数组,则将项目作为对象的键,并 return 可能找到的值。不用说,它适用于任意数量的组,具体取决于数据集。

function getGouped(array, groups) {
    function getValue(object, key) {
        return Array.isArray(key)
            ? key.reduce((o, k) => (o || {})[k], object)
            : object[key];
    }

    var result = [],
        object = { _: { children: result } };

    array.forEach(function (o) {
        groups.reduce(function (r, k) {
            var name = getValue(o, k);
            if (!r[name]) {
                r[name] = { _: { name, count: 0 } };
                r._.children = r._.children || [];
                r._.children.push(r[name]._);
            }
            r[name]._.count++;
            return r[name];
        }, object);
    });
    return result;
}

var data = [{ account: { id: 123, name: "worker" }, fromCountry: "TE", status: "created" }, { account: { id: 3, name: "worker" }, fromCountry: "TE", status: "pending" }, { account: { id: 123, name: "worker" }, fromCountry: "TE", status: "created" }, { account: { id: 1, name: "CEO" }, fromCountry: "FE", status: "done" }, { account: { id: 1123, name: "worker" }, fromCountry: "FE", status: "created" }];

console.log(getGouped(data, ['fromCountry', ['account', 'name']]));
console.log(getGouped(data, ['fromCountry', ['account', 'name'], 'status']));
.as-console-wrapper { max-height: 100% !important; top: 0; }