3

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?

5
  • "All arrays should have the same length" is a completely different task, isn't it? Would cutting them be OK? If not, why fill with empty strings (especially as some arrays consist of numbers only)? Commented Nov 8, 2012 at 11:35
  • @Bergi: To resolve index problem am keeping them empty string, Ex. in d1['a'] & d2['a'] creating d3['a'] having array length 4. & now d1 doesn't have 'c' key & d2 has 'c' key which is mapping with d2['a'] but 10 of d1['a'], d1 doesn't have 'c' key thats why keeping d3['c'][3] as empty string. Commented Nov 8, 2012 at 11:52
  • Index problem? Sounds like you want to solve it in the wrong place. Why don't you adapt the loop instead of creating empty strings? Commented Nov 8, 2012 at 11:57
  • @Bergi: Please have look at my actual object with few keys. let me know if you still have confusion. Commented Nov 8, 2012 at 12:14
  • @Niks Did my edited answer not do what you were looking for? Are you not looking for equal-length fields anymore? I'm confused. I feel like your question now is very different from the original one you posed. Commented Nov 9, 2012 at 17:11

3 Answers 3

1

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");
Sign up to request clarification or add additional context in comments.

Comments

1

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

5 Comments

Correct me if I'm wrong, but .concat won't "merge", it will but all the values from one array next to the values from the other.
@Vinay: its working fine, But i want unique merging values in each array
@Niks use Vinary 's code but replace the .concat() parts with Underscore's union funcion: underscorejs.org/#union
No I have posted new code that should merge only unique values (no duplicates). No need for underscore.
@Vinay: Its working awsm but need one more help, please have look at edited question.
0
function merge(a,b) {
    var c = {};
    for(key in a.keys()) {
        c[key] = a[key].slice(0);
    }
    for(key in b.keys()) {
        if(typeof c[key] == 'undefined') {
            c[key] = b[key].slice(0);
        } else {
            var adds = b[key].filter(function(item){ 
                return (a[key].indexOf(item) == -1);
            });
            c[key].concat(adds);
        }
    }
    return c;
}

Comments

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.