Reputation: 737
So the scenario is that I have this following array as my input:
[
{
"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"
}
]
the above array contains objects which hold the data regarding test cases
And I want an array like this:
[
{
"testSetName": "search",
"testCases": ["KEY-4855", "KEY-4857"]
},
{
"testSetName": "download",
"testCases": ["KEY-4856", "KEY-4858"]
},...
]
The above array contains objects and those objects hold the name of the test set(testSetName
) and all the test cases which are part of this test set as testCases
.
Now, my code is below:
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);
My code generates accurate results but I want to make it more efficient and I need help on this.
Upvotes: 0
Views: 60
Reputation: 386660
You could group by testSetName
and reduce the array with a lookup for an already inserted item.
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);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 5936
What you want to achieve contains an algorithm often called "group by". There is a lodash implementation you can use: _.groupBy
This will give you an object indexed by "testSetName". Then you can go forward and map
this to your desired structure.
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: {}}, ...]}]
This is more efficient in terms of "lines of code", but how the performance compares is hard to guess. If you don't face millions of entries, I would not bother.
Upvotes: 1