Working with X-layer array in JS

Asked

Viewed 240 times

4

I have a big problem, I have researched several places and I have not found the solution I hope you can help me... My goal is to create a JS function that will take an array as a base, which here I will call "To" his structure is this:

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

The function will receive another array, which I will call "B", follows its structure:

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

After the array "B" go through the function it must "exit" with the same structure as the "To" and the values that were missing in the "B" identical to that of "To", that is to say:

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 so far so good, my big question is, I have the array "To" as a basis, when I want to modify the structure of "To" let’s say 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 imagined so far this script would go wrong if I did that and it’s obvious I don’t want that to happen, what I really want is that array "B" when passing through the function, also receive the new layer...

I already started making this code but I can’t finish because of this damn question. Code I’ve already developed http://jsfiddle.net/mateusfmello/mja8ffs2/7/

  • Hello Matthew! I think you are calling Ray objects. This syntax d2: [e1 => "hello"], not Javascript. You mean d2: {e1: "hello"},?

  • Exactly, I will correct... Thanks for the remark... You know how I can resolve this issue?

  • Now I came up with another question, what to use? arrays or objects? what you suggest?

  • For the example you have seems to me that objects is better. I will then take a look and already comment. One question: these objects have only strings and numbers inside them? or DOM elements and others?

  • It can have numbers, strings and objects... The big question is the objects... You got to take a look at the code that is in jsfiddle?

  • Yes, I saw jsFiddle. I’m going to answer (if nobody is faster than me) but I wanted to know more information to give the right answer.

  • Last question: you say "It can have numbers, strings and objects" I wanted to know if these objects have something from DOM?

  • It will not contain, but will result graphics in canvas... the data that will be passed to the function is the canvas data...

Show 3 more comments

3 answers

3


An important part is to use a function that has a clear interface. That is, this function should have as a 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 logic of the function dup() can clone internal parts of the object original and also compare objects via their representation string saving more iterations on each other’s sub-objects when this is not necessary.

jsFiddle: http://jsfiddle.net/m4jqcvx0/1/

  • Sergio, aC = completarObjetos(obj, aC); shouldn’t be aCompletar[key] = completarObjetos(obj, aC);?

  • 1

    @falsarella I was thinking of objects that in the case would pass for reference. But can be strings... well seen, thank you. I corrected.

  • 1

    Face is that right there, vlw, it worked right... I’m new around here, and my reputation is low, but as soon as I’m over 15 I’ll come back and vote for your answer...

  • @Mateusfernandesdemello great that helped. Welcome! If you want you can mark the answer as accepted. Regardless of reputation.

  • Blz, I’ve already scored...

0

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

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

I hope you like it :D

Documentation: http://api.jquery.com/jquery.extend/

0

In certain structures of the objects the function entered in infinite loop, therefore I made a small change and I come to share with you

In

 else aC = completarObjetos(obj, aC);

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

How did the infinite loop occur? When the for (var key in original) { ended up going through every structure thus arriving at the last value, the variable key turned into a string with the value 0 (zero) and with that every time it passed the check if (dup(aC) == dup(obj)) gave as false, for aC returned M, because var aC = aCompletar[0]; so took the first letter of the name Matthew and obj returned w, because var obj = original[0]; So I picked up the first letter of the world name, remembering that this occurred in the last loop, being in

 d3: {
     2: "world"
 },

and how the verification if (dup(aC) == dup(obj)) returned false the executed code was the else aCompletar[key] = completarObjetos(obj, aC); so calling thousands of times the same function and occurring the same thing every time.

Codes: http://jsfiddle.net/mateusfmello/m4jqcvx0/4/

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

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

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.