Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge Object & Array: Javascript, JQuery

Illustrative example:

d1 = {
  "ean_code": ["OA13233394CN08", "8903327046534", "8903327014779"],
  "balance_qty": [5, 10, 15]
}

And

d2 = {
  "ean_code": ["OA13233394CN11", "OA13233394CN08", "8903327014779", "OA13233394CN09"],
  "scanned_qty": [30, 5, 20, 10, - 1],
}

Output:

d3 = {
  "ean_code": ["OA13233394CN08", "8903327046534", "8903327014779", "OA13233394CN11", "OA13233394CN09"],
  "scanned_qty": [5, 0, 20, 30, 10],
  "balance_qty": [5, 10, 15, 0, 0]
}

Explaination. d3['scanned_qty'][1] default value is 0, because value of d3['ean_code'][1] is belongs to d1['ean_code'] array and d1 object doesn't have scanned_qty key.

Best possible way to do this operation?

like image 620
Niks Jain Avatar asked Mar 11 '26 04:03

Niks Jain


2 Answers

You just need a custom solution for your specific case.

  • Merge 2 objects with no sub-objects (no recursion required)
  • Final object's array fields must be the same length
  • Final object's array fields must preserve index coherency
  • Final object's array fields must use '0' as a default value

http://jsfiddle.net/8X5yB/4/

function customMerge(a, b, uniqueKey) {
    var result = {};
    var temp = {};
    var fields = {};
    // object 1
    for(var x=0; x<a[uniqueKey].length; x++) {
        id = a[uniqueKey][x];
        if(temp[id] == null) temp[id] = {};
        for(k in a) {
            if(k != uniqueKey) {
                fields[k] = '';
                temp[id][k] = (a[k].length > x ? a[k][x] : 0);
            }
        }
    }
    // object 2
    for(var x=0; x<b[uniqueKey].length; x++) {
        id = b[uniqueKey][x];
        if(temp[id] == null) temp[id] = {};
        for(k in b) {
            if(k != uniqueKey) {
                fields[k] = '';
                temp[id][k] = (b[k].length > x ? b[k][x] : 0);
            }
        }
    }
    // create result
    result[uniqueKey] = [];
    for(f in fields) result[f] = [];
    for(k in temp) {
        result[uniqueKey].push(k);
        for(f in fields) {
            result[f].push(temp[k][f] != null ? temp[k][f] : 0);
        }
    }
    return result;
}
...
var obj = customMerge(d1, d2, "ean_code");
like image 75
Louis Ricci Avatar answered Mar 12 '26 19:03

Louis Ricci


Let's assume you have o1 and o2 as object 1 and 2, respectively.

var key,
    result = {}
    i,
    largestLength = 0,
    copyIntoResult = function (obj, key) {
        for (i = 0; i < obj[key].length; i += 1) {
            if (result[key].indexOf(obj[key][i]) === -1) {
                result[key].push(obj[key][i]);
            }
        }
    };

for (key in o1) {
    if (o1.hasOwnProperty(key) && o2.hasOwnProperty(key)) {
        result[key] = [];
        copyIntoResult(o1, key);
        copyIntoResult(o2, key);
        if (result[key].length > largestLength) {
            largestLength = result[key].length;
        }
    } else if (o1.hasOwnProperty(key)) {
        result[key] = [].concat(o1[key]);
        if (o1[key].length > largestLength) {
            largestLength = o1[key].length;
        }
    }
}
for (key in o2) {
    if (o2.hasOwnProperty(key) && !result[key]) {
        result[key] = [].concat(o2[key]);
        if (o2[key].length > largestLength) {
            largestLength = o2[key].length;
        }
    }
}

// result now has the merged result

for (key in result) {
    if (result[key].length < largestLength) {
        for (i = 0; i < (largestLength - result[key].length); i += 1) {
            result[key].push('');
        }
    }
}

EDIT: Upon the edit to your question, you can have all the arrays be the same length by equalizing the arrays to the maximum array length of the merged result. However, the default "blank" entry is up to you (in this case, I just used an empty string).

like image 39
Vinay Avatar answered Mar 12 '26 18:03

Vinay