Builda
Builda

Reputation: 47

group array object by multiple properties

I'm trying to group the following array with objects base on the siteId:

var Details = [
   {
       "addressId": "399906",
       "extAddressId": null,
       "addressType": "ORDER_FULFILLMENT",
       "siteId": 101,
       "bankAccount": [
              {"bankAccountId": "409539","extBankAccountId":null,"primary": true},
              {"bankAccountId": "409537","extBankAccountId": null, "primary": false},
              {"bankAccountId": "399907", "extBankAccountId": null, "primary": false}
       ],
       "contactId": ["399908"],
       "extContactId": null,
       "emailForPurchaseOrders": "[email protected]",
       "emailForRemittance": "[email protected]",
       "emailLanguage": "English"
   },
   {
       "addressId": "399906",
       "extAddressId": null,
       "addressType": "LEGAL",
       "siteId": 101,
       "bankAccount": [
             {"bankAccountId": "399907", "extBankAccountId": null, "primary": false}
             {"bankAccountId": "409540","extBankAccountId":null,"primary": true},
       ],
       "contactId": [],
       "extContactId": null,
       "emailForPurchaseOrders": "[email protected]",
       "emailForRemittance": "[email protected]",
       "emailLanguage": "English"
   }
]

To something like this:

{
   "addressId": ["399906"],
   "addressType": ["ORDER_FULFILLMENT", "LEGAL"],
   "siteId": 101,
   "bankAccount": [
        {
           "bankAccountId": "409539",
           "extBankAccountId": null,
           "primary": true
        },
        {
           "bankAccountId": "409537",
           "extBankAccountId": null,
           "primary": false
        },
        {
           "bankAccountId": "399907",
           "extBankAccountId": null,
           "primary": false
        },
        {
            "bankAccountId":"409540",
            "extBankAccountId":null,
            "primary": true
        },
    ],
    "contactId": ["399908"],
    "emailForPurchaseOrders": ["[email protected]", "[email protected]"],
    "emailForRemittance": ["[email protected]","[email protected]"],
    "emailLanguage": "English"
},

Right now I'm trying to group it but could not get the above structure to meet my needs. so far this is what i am trying to do to achieve it. Any help be highly appreciated.

       var group_to_values = subscriptionDetail.reduce(function (obj, item) {
            obj[item.siteId] = obj[item.siteId] || [];
            obj[item.siteId].push(item);
            return obj;
        }, {});
        console.log(group_to_values);
        var groups = Object.keys(group_to_values).map(function (key) {
            return {siteId: key, details: group_to_values[key]};
        });

I know I'm missing something but can't figure it out. Any suggestion?

Upvotes: 1

Views: 341

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386650

You could use some helper arrays for the wanted types of the target properties.

Extended with a hash table for same siteId.

var data = [{ addressId: "399906", extAddressId: null, addressType: "ORDER_FULFILLMENT", siteId: 101, bankAccount: [{ bankAccountId: "409539", extBankAccountId: null, primary: true }, { bankAccountId: "409537", extBankAccountId: null, primary: false }, { bankAccountId: "399907", extBankAccountId: null, primary: false }], contactId: ["399908"], extContactId: null, emailForPurchaseOrders: "[email protected]", emailForRemittance: "[email protected]", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "LEGAL", siteId: 101, bankAccount: [{ bankAccountId: "399907", extBankAccountId: null, primary: false }, { bankAccountId: "409540", extBankAccountId: null, primary: true }], contactId: [], extContactId: null, emailForPurchaseOrders: "[email protected]", emailForRemittance: "[email protected]", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "ORDER_FULFILLMENT", siteId: 102, bankAccount: [{ bankAccountId: "409539", extBankAccountId: null, primary: true }, { bankAccountId: "409537", extBankAccountId: null, primary: false }, { bankAccountId: "399907", extBankAccountId: null, primary: false }], contactId: ["399908"], extContactId: null, emailForPurchaseOrders: "[email protected]", emailForRemittance: "[email protected]", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "LEGAL", siteId: 102, bankAccount: [{ bankAccountId: "399907", extBankAccountId: null, primary: false }, { bankAccountId: "409540", extBankAccountId: null, primary: true }], contactId: [], extContactId: null, emailForPurchaseOrders: "[email protected]", emailForRemittance: "[email protected]", emailLanguage: "English" }],
    hash = Object.create(null),
    result = [],
    singleKeys = ['siteId', 'emailLanguage'];

data.forEach(function (o) {
    if (!hash[o.siteId]) {
        hash[o.siteId] = {};
        result.push(hash[o.siteId]);
    }
    Object.keys(o).forEach(function (k) {
        if (o[k] === null) {
            return;
        }
        if (singleKeys.indexOf(k) !== -1) {
            hash[o.siteId][k] = o[k];
            return;
        }
        hash[o.siteId][k] = hash[o.siteId][k] || [];
        if (Array.isArray(o[k])) {
            Array.prototype.push.apply(hash[o.siteId][k], o[k]);
            return;
        }
        if (hash[o.siteId][k].indexOf(o[k]) === -1) {
            hash[o.siteId][k].push(o[k]);
        }
    });
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Code which prevents duplicate objects with same bankAccountId, by iterating the array for inserting objects and check if the same bankAccountId already exist. If not push the actual object to the array.

var data = [{ addressId: "399906", extAddressId: null, addressType: "ORDER_FULFILLMENT", siteId: 101, bankAccount: [{ bankAccountId: "409539", extBankAccountId: null, primary: true }, { bankAccountId: "409537", extBankAccountId: null, primary: false }, { bankAccountId: "399907", extBankAccountId: null, primary: false }], contactId: ["399908"], extContactId: null, emailForPurchaseOrders: "[email protected]", emailForRemittance: "[email protected]", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "LEGAL", siteId: 101, bankAccount: [{ bankAccountId: "399907", extBankAccountId: null, primary: false }, { bankAccountId: "409540", extBankAccountId: null, primary: true }], contactId: [], extContactId: null, emailForPurchaseOrders: "[email protected]", emailForRemittance: "[email protected]", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "ORDER_FULFILLMENT", siteId: 102, bankAccount: [{ bankAccountId: "409539", extBankAccountId: null, primary: true }, { bankAccountId: "409537", extBankAccountId: null, primary: false }, { bankAccountId: "399907", extBankAccountId: null, primary: false }], contactId: ["399908"], extContactId: null, emailForPurchaseOrders: "[email protected]", emailForRemittance: "[email protected]", emailLanguage: "English" }, { addressId: "399906", extAddressId: null, addressType: "LEGAL", siteId: 102, bankAccount: [{ bankAccountId: "399907", extBankAccountId: null, primary: false }, { bankAccountId: "409540", extBankAccountId: null, primary: true }], contactId: [], extContactId: null, emailForPurchaseOrders: "[email protected]", emailForRemittance: "[email protected]", emailLanguage: "English" }],
    hash = Object.create(null),
    result = [],
    singleKeys = ['siteId', 'emailLanguage'];

data.forEach(function (o) {
    if (!hash[o.siteId]) {
        hash[o.siteId] = {};
        result.push(hash[o.siteId]);
    }
    Object.keys(o).forEach(function (k) {
        if (o[k] === null) {
            return;
        }
        if (singleKeys.indexOf(k) !== -1) {
            hash[o.siteId][k] = o[k];
            return;
        }
        hash[o.siteId][k] = hash[o.siteId][k] || [];
        if (k === 'bankAccount') {
            o[k].forEach(function (a) {
                var found = hash[o.siteId][k].some(function (b) {
                    return a.bankAccountId === b.bankAccountId;
                });
                if (!found) {
                    hash[o.siteId][k].push(a);
                }
            });
            return;
        }
        if (Array.isArray(o[k])) {
            Array.prototype.push.apply(hash[o.siteId][k], o[k]);
            return;
        }
        if (hash[o.siteId][k].indexOf(o[k]) === -1) {
            hash[o.siteId][k].push(o[k]);
        }
    });
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 2

Evil Dr. PorkChop
Evil Dr. PorkChop

Reputation: 379

`

 var Details = [
    {
        "addressId": "399906",
        "extAddressId": null,
        "addressType": "ORDER_FULFILLMENT",
        "siteId": 101,
        "bankAccount": [
                {"bankAccountId": "409539","extBankAccountId":null,"primary": true},
                {"bankAccountId": "409537","extBankAccountId": null, "primary": false},
                {"bankAccountId": "399907", "extBankAccountId": null, "primary": false}
        ],
        "contactId": ["399908"],
        "extContactId": null,
        "emailForPurchaseOrders": "[email protected]",
        "emailForRemittance": "[email protected]",
        "emailLanguage": "English"
    }
    ]

    let detailTwo = Details.map(item => {
    let keys = Object.keys(item);
    let copy = Object.assign({}, item);
    keys.forEach( val => {
        if(Array.isArray(copy[val]) && val !== 'bankAccount') {
            copy[val] = copy[val][0];  
        }
        if(copy[val] === null) {
            delete copy[val];  
        }
    });
return copy;
});

console.log(detailTwo);

`

Upvotes: 0

Related Questions