skip to Main Content

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

2

Answers


  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.
    Login or Signup to reply.
  2. 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);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search