获得以下代码所需结果的更好方法

时间:2018-06-05 07:40:38

标签: javascript arrays reduce

所以场景是我将以下数组作为输入:

[
  {
    "failureMessage": "failed",
    "data": {
      "statusCode": 201,
      "body": {
        "id": "14975",
        "key": "KEY-4855"
      }
    },
    "testSetName": "search"
  },
  {
    "failureMessage": null,
    "data": {
      "statusCode": 201,
      "body": {
        "id": "14975",
        "key": "KEY-4856"
      }
    },
    "testSetName": "download"
  },
  {
    "failureMessage": "failed 2",
    "data": {
      "statusCode": 201,
      "body": {
        "id": "14975",
        "key": "KEY-4857"
      }
    },
    "testSetName": "search"
  },
  {
    "failureMessage": null,
    "data": {
      "statusCode": 201,
      "body": {
        "id": "14975",
        "key": "KEY-4858"
      }
    },
    "testSetName": "download"
  },
  {
    "failureMessage": "failed",
    "data": {
      "statusCode": 201,
      "body": {
        "id": "14975",
        "key": "KEY-4859"
      }
    },
    "testSetName": "backgrounds"
  },
  {
    "failureMessage": null,
    "data": {
      "statusCode": 201,
      "body": {
        "id": "14975",
        "key": "KEY-4860"
      }
    },
    "testSetName": "backgrounds"
  }
]

上面的数组包含保存有关测试用例的数据的对象

我想要一个这样的数组:

[
  {
    "testSetName": "search",
    "testCases": ["KEY-4855", "KEY-4857"]
  },
  {
    "testSetName": "download",
    "testCases": ["KEY-4856", "KEY-4858"]
  },...
]

上面的数组包含对象,这些对象包含测试集的名称(testSetName)以及作为此测试集的一部分的所有测试用例testCases

现在,我的代码如下:

  let results = testCasesObject.reduce(function (previousArr, currElement, currIndex) {

      if (previousArr.length === 0) {
        let obj = {testSetName: currElement.testSetName, testCases: []};
        obj.testCases.push(currElement.data.body.key);
        previousArr.push(obj);
      }
      else {
        let isAdded = false;
        for (let index = 0; index < previousArr.length; index += 1) {
          if (previousArr[index].testSetName === currElement.testSetName) {
            previousArr[index].testCases.push(currElement.data.body.key);
            isAdded = true;
          }
        }
        if (!isAdded) {
          let obj = {testSetName: currElement.testSetName, testCases: []};
          obj.testCases.push(currElement.data.body.key);
          previousArr.push(obj);
        }
      }

        return previousArr;
    }, []);

    console.log(results);

我的代码生成了准确的结果,但我想提高效率,我需要帮助。

2 个答案:

答案 0 :(得分:1)

您想要实现的目标包含一个通常称为“分组依据”的算法。您可以使用lodash实现:_.groupBy

这将为您提供一个由“testSetName”索引的对象。然后你可以前进map到你想要的结构。

const indexedByTestSetName = _.groupBy(data, item => item.testSetName)
// {search: [{testSetName: 'search', failureMessage: 'failed', data: {}}, ...]
const tests = Object.keys(indexedByTestSetName).map(key => ({
  testSetName: key,
  testCases: indexedByTestSetName[key]
)})
// [{testSetName: 'search', testCases: [{testSetName: 'search', failureMessage: 'failed', data: {}}, ...]}]

这在“代码行”方面更有效,但性能比较难以猜测。如果你没有面对数百万的参赛作品,我不会打扰。

答案 1 :(得分:1)

您可以按testSetName进行分组,并通过查找已插入的项目来缩小数组。

&#13;
&#13;
var array = [{ failureMessage: "failed", data: { statusCode: 201, body: { id: "14975", key: "KEY-4855" } }, testSetName: "search" }, { failureMessage: null, data: { statusCode: 201, body: { id: "14975", key: "KEY-4856" } }, testSetName: "download" }, { failureMessage: "failed 2", data: { statusCode: 201, body: { id: "14975", key: "KEY-4857" } }, testSetName: "search" }, { failureMessage: null, data: { statusCode: 201, body: { id: "14975", key: "KEY-4858" } }, testSetName: "download" }, { failureMessage: "failed", data: { statusCode: 201, body: { id: "14975", key: "KEY-4859" } }, testSetName: "backgrounds" }, { failureMessage: null, data: { statusCode: 201, body: { id: "14975", key: "KEY-4860" } }, testSetName: "backgrounds" }],            
    result = array.reduce((r, { testSetName, data: { body: { key } } }) => {
        var item = r.find(o => o.testSetName === testSetName);
        if (item) {
            item.testCases.push(key);
        } else {
            r.push({ testSetName, testCases: [key] });
        }
        return r;
    }, []);
   
console.log(result);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;