3

I have two arrays of objects:

var arOne = [
    {key: 'alpha', value: 5},  
    {key: 'beta', value: 11},  
    {key: 'gamma', value: 15},  
    {key: 'delta', value: 12},  
    {key: 'epsilon', value: 55}  
    {key: 'pony', value: 101}
]

var arTwo = [
    {key: 'alpha', value: 5.5},  
    {key: 'beta', value: 11.5},  
    {key: 'gamma', value: 15.5},  
    {key: 'psi', value: 12.5},  
    {key: 'omega', value: 55.5}  
]

I need to merge values into one array of arrays.

Case where the keys match: create an array with the key and append the value from arTwo to arOne.

Case where the keys do not match: if the key exists in arOne, I include the value from arOne and a 0 for arTwo. If the key exists in arTwo, I include a 0 for arOne and the value from arTwo.

Note that arOne and arTwo may be different sizes (see the pony key in arOne).

This is what the result should look like:

var result = [
    ['alpha', 5, 5.5],  
    ['beta', 11, 11.5],  
    ['gamma', 15, 15.5],  
    ['delta', 12, 0],  
    ['epsilon', 55, 0],  
    ['pony', 101, 0],
    ['psi', 0, 12.5],  
    ['omega', 0, 55.5],  
]

I've been staring at this all day and scratched all my attempts. Any thoughts?

2
  • 2
    What have you tried? I would suggest two loops, one looping through the first array and populating result, and the other looping through the second and adding new entries to result. Commented Dec 7, 2012 at 19:38
  • I tried $.each() which didn't work because the arrays are different sizes. I tried a nested for loop but couldn't figure out how to access the values in the objects. I was hoping jQuery had a semi-elegant solution but perhaps not. Commented Dec 7, 2012 at 19:48

3 Answers 3

2
function combine(obj1, obj2){
    var arr = [], k, i;
    for (k = 0; k < obj1.length; ++k){
        arr.push([obj1[k].key, obj1[k].value]);
    }
    for (k = 0; k < obj2.length; ++k){
        var exists = false;
        for (i = 0; i < arr.length; ++i){
            if(arr[i][0] === obj2[k].key){
               arr[i].push(obj2[k].value);
               var exists = true; 
               break;
            }
        }
        if (!exists){
            arr.push([obj2[k].key, 0, obj2[k].value]);
        }
    }
    for (i = 0; i < arr.length; ++i){
        if (arr[i].length === 2){
            arr[i].push(0);
        }
    }

    return arr;
}

Call like:

var myNewArray = combine(arOne, arTwo);
Sign up to request clarification or add additional context in comments.

5 Comments

This doesn't work. It's doesn't give the 0 for the missing value the OP wanted. Shame on me. I shall edit.
I could be mistaking, but the way I see it your first loop pushes the index k into the array instead of the value obj1[k].key.
You have to consider that he is asking to merge to arrays full of objects.
@Mathias fixed! yeah, I missed that array of objects thing, thought it was straight objects at first.
I know - I did the same thing when I started writing my reply :)
1

ok.. i managed it

var tmp_result = {}; // we need this object to make things easy
var result = [];

// add all elements in first array to result, im using this as an object so that I can easily find the keys later
$.each(arOne, function (index, element) {
    tmp_result[element.key] = [element.key, element.value];
});


// loop through second array    
$.each(arTwo, function (index, element) {
    // check if this was key already added
    if (tmp_result[element.key] != undefined) {
        // if it was added earlier then add the new key
        tmp_result[element.key].push(element.value);
    } else {
        // create a new key, add 0 in between since its not there in first array
        tmp_result[element.key] = [element.key, 0, element.value];
    }
});

// now we are left with all those elements which are in first array but not in second
$.each(tmp_result, function (key, element) {
    // check if the array has 3 elements, if not then add 0 in the end since its not there in second one
    if (element.length < 3) element.push(0);
    // pass the flattened out data to result array
    result.push(element);
});

console.log(result);

Fiddle - http://jsfiddle.net/atif089/McfUk/

My output was

[
    ["alpha", 5, 5.5], 
    ["beta", 11, 11.5], 
    ["gamma", 15, 15.5], 
    ["delta", 12, 0], 
    ["epsilon", 55, 0], 
    ["pony", 101, 0], 
    ["psi", 0, 12.5], 
    ["omega", 0, 55.5]
]

2 Comments

This is a copy of my answer... except that you create an object then push the object to an array. It's also poor practice to use jQuery (or any library) for functions simple enough accomplish easily without them.
sorry, I was busy typing the code and didn't look at your answer. Regarding $.each, yes I agree
1

Here is simple take on it. You loop over the first array and push the data into the result array. A Little trickier when you loop over the second. You take each key value pair and check if that key exists in the result array already. If so add it, if not ( found = false ) add it to the result array:

var result = [];
var i;

for ( i = 0; i < arOne.length; i++ ) {
    result.push( [ arOne[ i ].key, arOne[ i ].value ] );
}

for ( i = 0; i < arTwo.length; i++ ) {
    var key = arTwo[ i ].key;
    var value = arTwo[ i ].value;
    var found = false;

    for ( var k = 0; k < result.length; k++ ) {
        if ( result[ k ][ 0 ] === key ) {
            result[ k ].push( value );
            found = true;
        }
    }

    if ( ! found ) {
        result.push( [ key, value ] );
    }

}

result is the array you wanted. Probably not the most efficient way to do it. But it gets the job done.

Also, on a small note. You might want to consider using and object instead of nested arrays. So that your result looks something like this:

var result = {
    alpha: [5, 5.5],  
    beta: [11, 11.5],  
    gamma: [15, 15.5],  
    delta: [12, 0],  
    epsilon: [55, 0],  
    pony: [101, 0],
    psi: [0, 12.5],  
    omega: [0, 55.5], 
}

This might be easier to handle your data later in the code.

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.