0

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);
4
  • Please add the code you've attempted to your question as a minimal reproducible example. Commented Dec 30, 2022 at 19:56
  • @Andy code has been added Commented Dec 30, 2022 at 20:11
  • Basically, you want to group/collate/pivot by (exact!) address? Commented Dec 30, 2022 at 21:10
  • @skreutzer yes that’s basically it :) Commented Dec 30, 2022 at 21:31

2 Answers 2

1

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 the nested 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);

Sign up to request clarification or add additional context in comments.

Comments

1

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

  1. Fields saleNo and deliveryTo are always an Array even if there's just one value - you could adapt the example on first adding a string, and if it's not undefined, checking if it's an Array to simply add the new value, or otherwise replace the string with an Array that contains the first value. Not elegant, but easy to read/follow what's happening. Problem of course would be that on reading the result, you again have to handle this variance, instead of just always having an Array.

4 Comments

this is very helpful thank you! would love to have the address key back though rather than the address as the key any suggestions?
Updated, at the expense of the stupid/lazy extra inner loop (OK, maybe there's a search/find function on value/member, or even more advanced language constructs, here just doing something quick&simple&dirty).
This can be slow for a large data set, e.g. O(n*n) because of the nested for loops
Absolutely! :-( :-) Was not the desired result to use the address as an array index for fast lookup, also didn't make a separate address-to-index mapping array which would then grow memory. Therefore there's now your answer/solution :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.