Working with array with X layers in JS

4

I have a big problem, I already researched in several places and I did not find the solution I hope you can help me ... My goal is to create a function in JS that will get an array as a base, which I will call here as " A " its structure is this:

var A = {
        a1: {
            c1: 50,
            c2: 50,
        },
        b1: {
            d1: 0,
            d2: [1 => "hello"],
            d3: [2 => "world"],
        }
    };

The function will get another array, which I'll call " B ", it follows the structure of it:

var B = {
        a1: {
            c1: 1,
            c2: 125,
        },
    };

After the array " B " pass through the function it should "exit" with the structure identical to " A " and with the missing values in " B "identical to" A ", ie:

Array " B " after passing the function:

var B = {
        a1: { /* índice que já existia no array "B" */
            c1: 1, /* índice e valor que já existia no array "B" */
            c2: 125, /* índice e valor que já existia no array "B" */
        },
        b1: { /* índice que NÂO existia no array "B" e como o array "A" é a base foi criado esse índice no array "B" */
            d1: 0, /* índice e valor que não existia no array "B", é a mesma história do b1 aqui em cima */
            d2: [1 => "hello"], /* mesmo caso dos outros dois acima */
            d3: [2 => "world"], /* mesmo caso dos outros três acima */
        }
    };

Let's say that's fine, my big question is, I have the array " A " as a basis, when I want to modify the " A structure" add one more level to it as in the example:

var A2 = {
        a1: {
            c1: 50,
            c2: 50,
        },
        b1: {
            d1: 0,
            d2: [e1 => "hello"],
            d3: [
                   f2 => "world",
                   f3 => [
                            g1 => "nova",
                            g2 => "camada"
                         ]
                ],
        }
    };

The way I figured this script would go wrong if I did this and it's obvious that I do not want this to happen, what I really want is for the array " B " to pass through function, also receive the new layer ...

I've already started to do this code, but I can not finish it because of this damn doubt. Code that I have already developed link

    
asked by anonymous 01.07.2015 / 21:25

3 answers

3

An important part is to use a function that has a clear interface. In other words, this function should have the function / order to compare what is given to it and nothing else.

So I suggest something like this:

function completarObjetos(original, aCompletar) {
    function dup(o) {
        return JSON.parse(JSON.stringify(o));
    };

    for (var key in original) {
        var obj = original[key];
        var aC = aCompletar[key];
        if (aC) {
            if (dup(aC) == dup(obj)) continue;
            else aCompletar[key] = completarObjetos(obj, aC);
        } else {
            aCompletar[key] = dup(obj);
        }
    }
    return aCompletar;
}
Using the dup() function logic you can clone internal parts of the original object and also compare objects via their string representation by saving more iterations in the sub-objects of each when this is not necessary.

jsFiddle: link

    
01.07.2015 / 23:09
0

In certain object structures the function would loop in infinite, so I made a small change and I have to share with you

In

 else aC = completarObjetos(obj, aC);

I added the following check else if (typeof obj == "object") aC = comple... this way the infinite loop no longer occurs.

How did the infinite loop occur? When for (var key in original) { ended up traversing every structure thus arriving at the last value, the variable key turned a string with the value 0 (zero) and with that every time it passed in the check if (dup(aC) == dup(obj)) it gave false , because aC returned M, because var aC = aCompletar[0]; being thus got the first letter of the name Mateus and obj returned w, therefore var obj = original[0]; being thus got the first letter of the name world, remembering that this happened in last loop, being in

 d3: {
     2: "world"
 },

and since the if (dup(aC) == dup(obj)) check returned false the executed code was the else aCompletar[key] = completarObjetos(obj, aC); thus calling the same function thousands of times and the same thing always happens.

Codes: link

Remove if (typeof obj == "object") from line 44 and now add

console.log(key);
console.log(typeof key);

On line 38, open the console of your browser (F12), run the code by clicking "Run" and note the error ...

    
03.07.2015 / 15:24
0

I just found what I wanted, $.extend(true, param1, param2); , but it depends on jQuery.

It works as follows, true informs that we want to add data from param2 to param1 recursively, as we can already see it seems that param2 has all data and param1 that could is missing, but it is not so, param1 would be the object that you have all the data would be in the default case, so param2 is the parameter that will pass new data, or else customize the data param1 .

I hope you like it: D

Documentation: link

    
10.07.2015 / 14:07