I’m looking for a way to combine JSON objects if they have the same address
value in them. Building off this Combining JSON Question I have these two sample JSON
files. Would love any suggestions thank you so much.
Before Combining:
[
{
"saleNo": "86131",
"address": "6562 Dagmar Haven Suite 593 Warner Robins WI, 68085-5440",
"deliveryTo": "Earl Bruen"
},
{
"saleNo": "82483",
"address": "6562 Dagmar Haven Suite 593 Warner Robins WI, 68085-5440",
"deliveryTo": "Harold Kuhn"
},
{
"saleNo": "53731",
"address": "33194 Royal Track Suite 501 Enid CO, 57355",
"deliveryTo": "Kristopher Bayer"
},
{
"saleNo": "12285",
"address": "183 Lazaro Meadow Suite 841 Council Bluffs AL, 52499",
"deliveryTo": "Cassandra Mueller"
},
{
"saleNo": "23404",
"address": "89319 Witting Green Suite 924 Portland MN, 74633-9170",
"deliveryTo": "Chris Thiel Sr."
},
{
"saleNo": "70528",
"address": "2410 Zaria Forges Suite 936 St. Louis GA, 94962-5376",
"deliveryTo": "Glenda Larson"
}
]
After Combining:
[
{
"saleNo": ["86131", "82483"],
"address": "6562 Dagmar Haven Suite 593 Warner Robins WI, 68085-5440",
"deliveryTo": ["Harold Kuhn", "Earl Bruen"]
},
{
"saleNo": "53731",
"address": "33194 Royal Track Suite 501 Enid CO, 57355",
"deliveryTo": "Kristopher Bayer"
},
{
"saleNo": "12285",
"address": "183 Lazaro Meadow Suite 841 Council Bluffs AL, 52499",
"deliveryTo": "Cassandra Mueller"
},
{
"saleNo": "23404",
"address": "89319 Witting Green Suite 924 Portland MN, 74633-9170",
"deliveryTo": "Chris Thiel Sr."
},
{
"saleNo": "70528",
"address": "2410 Zaria Forges Suite 936 St. Louis GA, 94962-5376",
"deliveryTo": "Glenda Larson"
}
]
Sample Code:
let data = [
{
"saleNo": "86131",
"address": "6562 Dagmar Haven Suite 593 Warner Robins WI, 68085-5440",
"deliveryTo": "Earl Bruen"
},
{
"saleNo": "82483",
"address": "6562 Dagmar Haven Suite 593 Warner Robins WI, 68085-5440",
"deliveryTo": "Harold Kuhn"
},
{
"saleNo": "53731",
"address": "33194 Royal Track Suite 501 Enid CO, 57355",
"deliveryTo": "Kristopher Bayer"
},
{
"saleNo": "12285",
"address": "183 Lazaro Meadow Suite 841 Council Bluffs AL, 52499",
"deliveryTo": "Cassandra Mueller"
},
{
"saleNo": "23404",
"address": "89319 Witting Green Suite 924 Portland MN, 74633-9170",
"deliveryTo": "Chris Thiel Sr."
},
{
"saleNo": "70528",
"address": "2410 Zaria Forges Suite 936 St. Louis GA, 94962-5376",
"deliveryTo": "Glenda Larson"
}
]
let result = Object.values(data.reduce((c, {address,numbers}) => {
c[address] = c[address] || {address,numbers: []};
c[address].numbers = c[address].numbers.concat(Array.isArray(numbers) ? numbers : [numbers]);
return c;
}, {}));
console.log(result);
CodePudding user response:
So what about
let result = new Array();
for (let dataIndex = 0, dataMax = data.length; dataIndex < dataMax; dataIndex ) {
let address = data[dataIndex]["address"];
let target = null;
for (let resultIndex = 0, resultMax = result.length; resultIndex < resultMax; resultIndex ) {
if (result[resultIndex].address == address) {
target = result[resultIndex];
break;
}
}
if (target == null) {
result.push({ address: address, saleNo: new Array(), deliveryTo: new Array() });
target = result[result.length - 1];
}
target.saleNo.push(data[dataIndex].saleNo);
target.deliveryTo.push(data[dataIndex].deliveryTo);
}
not doing anything clever? Result is not exactly the desired result, because
- Fields
saleNo
anddeliveryTo
are always anArray
even if there's just one value - you could adapt the example on first adding a string, and if it's notundefined
, checking if it's anArray
to simply add the new value, or otherwise replace the string with anArray
that contains the first value. Not elegant, but easy to read/follow what's happening. Problem of course would be that on reading theresult
, you again have to handle this variance, instead of just always having anArray
.
CodePudding user response:
This solution uses:
- reduce to create a map of addresses, that contains maps of saleNo and deliveryTo (in order to weed out duplicates)
- Object.entries and map to to convert the nested maps to the desired output
This reduce and map solution is faster than th enested for loops approach for large datasets, e.g. O(2n) vs. O(n*n)
let data = [ { "saleNo": "86131", "address": "6562 Dagmar Haven Suite 593 Warner Robins WI, 68085-5440", "deliveryTo": "Earl Bruen" }, { "saleNo": "82483", "address": "6562 Dagmar Haven Suite 593 Warner Robins WI, 68085-5440", "deliveryTo": "Harold Kuhn" }, { "saleNo": "53731", "address": "33194 Royal Track Suite 501 Enid CO, 57355", "deliveryTo": "Kristopher Bayer" }, { "saleNo": "12285", "address": "183 Lazaro Meadow Suite 841 Council Bluffs AL, 52499", "deliveryTo": "Cassandra Mueller" }, { "saleNo": "23404", "address": "89319 Witting Green Suite 924 Portland MN, 74633-9170", "deliveryTo": "Chris Thiel Sr." }, { "saleNo": "70528", "address": "2410 Zaria Forges Suite 936 St. Louis GA, 94962-5376", "deliveryTo": "Glenda Larson" } ]
let result = Object.entries(data.reduce((acc, obj) => {
if(!acc[obj.address]) {
acc[obj.address] = {
saleNo: {},
deliveryTo: {}
};
}
acc[obj.address].saleNo[obj.saleNo] = true;
acc[obj.address].deliveryTo[obj.deliveryTo] = true;
return acc;
}, {})).map(arr => {
let address = arr[0];
let o = arr[1];
return {
saleNo: Object.keys(o.saleNo).sort(),
address: address,
deliveryTo: Object.keys(o.deliveryTo).sort()
}
});
console.log(result);