DGA
DGA

Reputation: 268

Javascript merge to array with some identical value at certain index

I have 2 arrays which i want to combine (merge), but if value at index 0 from first array is identical with value at index 0 on second array this must be in the same array. More details: Array 1:

var arr1 = [
    ["SP.22110000295", 1,      162.9],
    ["SP29372",        1,     1061.6],
    ["SP3204200014",   5,     1147.5],
    ["SP324035",       1, 94110.0231]
];

Array 2:

 var arr2  [
    ["999974",           1],
    ["SP.SAMBACR803805", 1],
    ["SP29193",          1],
    ["SP29372",          4],
    ["SP324035",         3]
]

As you can see (in this example), first array have another 4 array with 3 items, and second 5 array with 2 items. arr1[3][0] (["SP324035", 1, 94110.0231]) is equal with arr2[4][0] (["SP324035", 1])

so i don't know hot achieve a result like this:

var arrfinal = [
   ["SP.22110000295",     1,      162.9, null], // arr1 index 0 **is not** in arr2 index 0
   ["SP29372",            1,     1061.6,    4], // arr1 index 0 **is** in arr2 index 0
   ["SP3204200014",       5,     1147.5, null], // arr1 index 0 **is not** in arr2 index 0
   ["SP324035",           1, 94110.0231,    3], // arr1 index 0 **is** in arr2 index 0
   ["999974",          null,       null,    1], // arr2 index 0 **is not** in arr1 index 0
   ["SP.SAMBACR803805",null,       null,    1], // arr2 index 0 **is not** in arr1 index 0
   ["SP29193",         null,       null,    1]  // arr2 index 0 **is not** in arr1 index 0
];

Actualy it's not realy a merge, because just arrays where values of index 0 are equals are merged others it's kind of splice.

I tried with merge, expand splice... underscore, jquery...

Any hints please?

Thank you, very much, Geo

Upvotes: 0

Views: 60

Answers (1)

Paul S.
Paul S.

Reputation: 66314

What I understand from your question is you have two Arrays, arr1 and arr2, and you want to generate a new Array, arrfinal, with the folowing conditions

  1. Items from arr1 should be copied to arrfinal
  2. If there exists an arrfinal[i][0] === arr2[j][0] for some i, j, then items of arr[2][j] from index 1 should be appened to the end of the items from arr1[i] in arrfinal
  3. If this does not happen, push a new Array to arrfinal with index 0 of arr2[j][0] padded by nulls before appending the other items from arr2[j]
  4. All items in arrfinal should have the same length
var arrfinal = [],
    key_map = {},
    max_len_1 = 0,
    max_len_2 = 0,
    i, j;

for (i = 0; i < arr1.length; ++i) {
    max_len_1 = Math.max(max_len_1, arr1[i].length); // find maximum length of arr1
    arrfinal.push(arr1[i].slice()); // copy to final
    key_map[arr1[i][0]] = arrfinal.length - 1; // mapping for later
}

for (i = 0; i < arrfinal.length; ++i) { // fix lengths
    while (arrfinal[i].length < max_len_1) {
        arrfinal[i].push(null);
    }
}

for (i = 0; i < arr2.length; ++i) {
    max_len_2 = Math.max(max_len_2, arr2[i].length); // find maximum length of arr2
    if (key_map.hasOwnProperty(arr2[i][0])) { // entry exists from arr1
        j = key_map[arr2[i][0]];
    } else { // generate a new entry
        j = arrfinal.push([arr2[i][0]]) - 1;
        while (arrfinal[j].length < max_len_1) { // fix length
            arrfinal[j].push(null);
        }
    }
    Array.prototype.push.apply(
        arrfinal[j],
        arr2[i].slice(1)
    );
}

for (i = 0; i < arrfinal.length; ++i) { // fix lengths one last time
    while (arrfinal[i].length < max_len_1 + max_len_2 - 1) {
        arrfinal[i].push(null);
    }
}

It should be noted however, that this may give unexpected results if there exists multiple items which have the same value at index 0 per arr1 or arr2, for example

var arr1 = [
    [ 'foo',      1],
    ['fizz', 'buzz']
];
var arr2 = [
    ['foo', 'bar']
    ['foo', 'baz']
];

would result in

[
    [ 'foo',      1, 'bar', 'baz'],
    ['fizz', 'buzz',  null       ]
]

Further, if these are guaranteed to be unique then perhaps you should consider using an Object instead of an Array

Upvotes: 1

Related Questions