使用Underscore js过滤,分组和聚合数据

时间:2016-09-19 11:12:40

标签: javascript reactjs underscore.js

我有这样的原始数据:

var data = {
  "issues": [
    {
      "fields": {
        "project": {
          "key": "ProjectA"
        },
        "components": [
          {
            "name": "Component A"
          },
          {
            "name": "Component C"
          }
        ],
        "priority": {
          "name": "P0"
        },
        "status": {
          "name": "Closed"
        }
      }
    },
    {
      "fields": {
        "project": {
          "key": "ProjectA"
        },
        "components": [
          {
            "name": "Component B"
          }
        ],
        "priority": {
          "name": "P1"
        },
        "status": {
          "name": "Reopened"
        }
      }
    },
    {
      "fields": {
        "project": {
          "key": "ProjectA"
        },
        "components": [
          {
            "name": "Component B"
          }
        ],
        "priority": {
          "name": "P1"
        },
        "status": {
          "name": "Closed"
        }
      }
    },
    {
      "fields": {
        "project": {
          "key": "Project B"
        },
        "components": [
          {
            "name": "Component X"
          }
        ],
        "priority": {
          "name": "P1"
        },
        "status": {
          "name": "Closed"
        }
      }
    }
  ]
};

如果我将ProjectA作为输入,我想按如下方式过滤,分组和汇总输出:

"components": [
  {
    "name": "Component A",
    "priorities": [
      {
        "name": "P0",
        "status": [
          {
            "name": "Open",
            "count": 0
          },
          {
            "name": "Reopened",
            "count": 0
          },
          {
            "name": "Closed",
            "count": 1
          }
        ]
      },
      {
        "name": "P1",
        "status": [
          {
            "name": "Open",
            "count": 0
          },
          {
            "name": "Reopened",
            "count": 0
          },
          {
            "name": "Closed",
            "count": 0
          }
        ]
      }
    ]
  },
  {
    "name": "Component B",
    "priorities": [
      {
        "name": "P0",
        "status": [
          {
            "name": "Open",
            "count": 0
          },
          {
            "name": "Reopened",
            "count": 0
          },
          {
            "name": "Closed",
            "count": 0
          }
        ]
      },
      {
        "name": "P1",
        "status": [
          {
            "name": "Open",
            "count": 0
          },
          {
            "name": "Reopened",
            "count": 1
          },
          {
            "name": "Closed",
            "count": 1
          }
        ]
      }
    ]
  },
  {
    "name": "Component C",
    "priorities": [
      {
        "name": "P0",
        "status": [
          {
            "name": "Open",
            "count": 0
          },
          {
            "name": "Reopened",
            "count": 0
          },
          {
            "name": "Closed",
            "count": 1
          }
        ]
      },
      {
        "name": "P1",
        "status": [
          {
            "name": "Open",
            "count": 0
          },
          {
            "name": "Reopened",
            "count": 0
          },
          {
            "name": "Closed",
            "count": 0
          }
        ]
      }
    ]
  }
]

我尝试过链接,过滤,分组,但不知道如何使用它,因为我的数据太嵌套了。

1 个答案:

答案 0 :(得分:2)

这是一个普通javascript的提案,首先收集所有组件和优先级,然后构建一个结果对象,然后增加状态计数。

var data = { "issues": [{ "fields": { "project": { "key": "ProjectA" }, "components": [{ "name": "Component A" }, { "name": "Component C" }], "priority": { "name": "P0" }, "status": { "name": "Closed" } } }, { "fields": { "project": { "key": "ProjectA" }, "components": [{ "name": "Component B" }], "priority": { "name": "P1" }, "status": { "name": "Reopened" } } }, { "fields": { "project": { "key": "ProjectA" }, "components": [{ "name": "Component B" }], "priority": { "name": "P1" }, "status": { "name": "Closed" } } }, { "fields": { "project": { "key": "Project B" }, "components": [{ "name": "Component X" }], "priority": { "name": "P1" }, "status": { "name": "Closed" } } }] },
    componentsO = Object.create(null),
    prioritiesO = Object.create(null),
    components,
    priorities,
    status_ = ['Open', 'Reopened', 'Closed'], // status collides in chrome with window.status
    hash = Object.create(null),
    getKey = function (a) { return a.join('|'); },
    result = {};

data.issues.forEach(function (issue) {
    if (issue.fields.project.key === 'ProjectA') {
        issue.fields.components.forEach(function (component) {
            componentsO[component.name] = true;
        });
        prioritiesO[issue.fields.priority.name] = true;
    }
});

components = Object.keys(componentsO).sort();
priorities = Object.keys(prioritiesO).sort();

result.components = components.map(function (component) {
    return {
        name: component,
        priorities: priorities.map(function (priority) {
            return {
                name: priority,
                status: status_.map(function (status) {
                    var key = getKey([component, priority, status]);
                    hash[key] = { name: status, count: 0 };
                    return hash[key];
                })
            };
        })
    }
});

data.issues.forEach(function (issue) {
    if (issue.fields.project.key === 'ProjectA') {
        issue.fields.components.forEach(function (component) {
            var key = getKey([component.name, issue.fields.priority.name, issue.fields.status.name]);
            hash[key].count++;
        });
    }
});

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