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

时间:2018-06-25 11:58:51

标签: javascript flatten

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

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"
  }
]

我想按国家/地区对它们进行分组,对国家/地区进行计数,然后将名称类型保存在孩子中,并对其进行计数。因此它必须看起来像这样:

[
  {
    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库)

能帮我吗?

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

分组的另一个关键问题是如何获取嵌套属性。该分组值是通过一个辅助函数获取的,该函数检查给定键是否为数组。如果是数组,则将各项作为对象的键并返回可能找到的值。不用说,它适用于任意数量的组,具体取决于数据集。

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; }