0

I am trying to loop all the values of an array and push that looped data into another array.

For example:

{
"cat": [
    {
        "view": [
            {
                "ent": [
                    {
                        "data": [
                            {}
                        ],
                        "label": "abcd"
                    },
                    {
                        "data": [
                            {}
                        ],
                        "label": "efgh"
                    }
                ]
            }
        ]
    }
]

I need to iterate until label and bring all the values of label into an array. This is what I have tried. The issue is I am just getting the last value of label i.e. won in my array variable.

JS:

var ArrL = scope.res.cat;
var Array = [];
for(var i=0;i<ArrL.length;i++){
    var ArrF = ArrL[i].view;
    for(var j=0;j<ArrF.length;j++){
        var ArrE = ArrF[j].ent;
        for(var k=0;k<ArrE.length;k++){
            var ArrLa = ArrE[k].label;

        }

    }
    Array.push(ArrLa);
}
console.log(Array);

Expected output is ['joy','won'] but output after running the program is ['won'].

7
  • 1
    Where you have defined ArrLa? Commented Jun 25, 2014 at 9:26
  • 4
    seems an invalid json structure. },]. Commented Jun 25, 2014 at 9:27
  • 2
    It's not JSON at all, just a normal array. Trailing commas are bad form but work in most JS engines. Commented Jun 25, 2014 at 9:29
  • I just added the basic JSON, its not an actual JSON structure. ArrLa is just a variable.... Declared all the variables without var keyword Commented Jun 25, 2014 at 9:30
  • Trailing commas are lazy and fail big time in IE<9 Commented Jun 25, 2014 at 9:36

3 Answers 3

2

Since your Q is flagged as jquery, you can do this:

var cat = [
    {
        view: [
            {
                ent: [
                    {
                        data: [
                            {
                                key: "id",
                                value: "00"
                            }, 
                            {
                                key: "cid",
                                value: "123"
                            }
                        ],
                        label: "joy"
                    }, 
                    {
                        key: "id",
                        value: "11"
                    }, 
                    {
                        key: "cid",
                        value: "234"
                    }
                ], // end ent
                label: "won"
            }, 

        ] //end view
    }
];

var labels = [];

$.map( cat, function flattener( node ) {
    if ( $.isPlainObject( node ) && node.hasOwnProperty('label') ) {
        labels.push( node.label );
    }
    return ($.isArray( node ) || $.isPlainObject( node )) ? $.map( node, flattener) : node;
} );

console.log( labels );

Fiddle: http://jsfiddle.net/fFwQ6/

Thing to note is that order will be dictated by depth: deeper labels come last.

UPDATE: It is easy to turn it into an utility function:

function grabKeys( source, keyName ) {
    var values = [];

    $.map( source, function flattener( node ) {
        if ( $.isPlainObject( node ) && node.hasOwnProperty(keyName) ) {
            values.push( node[keyName] );
        }
        return ($.isArray( node ) || $.isPlainObject( node )) ? $.map( node, flattener) : node;
    } );

    return values;
}


var labels = grabKeys( cat, 'label' );
var cids = grabKeys( cat, 'cid' );

UPDATE 2: Since 'cid' is a key value and not a name, we must use a slightly different method. Sorry I did not noticed it previously.

function grabPairedKeys( source, keyValue, keyName1, keyName2 ) {
    keyName1 = keyName1 || 'key';
    keyName2 = keyName2 || 'value';

    var values = [];

    $.map( source, function flattener( node ) {
        if ( $.isPlainObject( node ) && node.hasOwnProperty(keyName1) && node.hasOwnProperty(keyName2) && node[keyName1] === keyValue ) {
            values.push( node[keyName2] );
        }
        return ($.isArray( node ) || $.isPlainObject( node )) ? $.map( node, flattener) : node;
    } );

    return values;
}


var labels = grabKeys( cat, 'label' );
var cids = grabPairedKeys( cat, 'cid' );
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much brother, your code is very minimal and gives the accurate values. If I need to have the value for the key "cid" along with label how to modify the code.
Thank you very much once again.... Expected output should be cid:["234","123"] and label:["won","joy"]. I am getting output only for label but not for cid, I changed the code of your previous fiddle and tried by replacing it with the updated one. Can you please attach the fiddle of expecting result. I am very much thankful to you....
Update 2 added. There was a small misconception.
1

You should use the push in the loop.

    for(var i=0;i<ArrL.length;i++){
                ArrF = ArrL[i].view;
                for(var j=0;j<ArrF.length;j++){
                    ArrE = ArrF[j].ent;
                    for(var k=0;k<ArrE.length;k++){
                        ArrLa = ArrE[k].label;
                        Array.push(ArrLa);
                    }

                }

            }

Comments

1

Well, you only push the last value that was assigned to ArrLa after having iterated the view array. Instead, push the value right away when you encounter it:

var Array = [];
for(var i=0;i<ArrL.length;i++){
    var ArrF = ArrL[i].view;
    for(var j=0;j<ArrF.length;j++){
        var ArrE = ArrF[j].ent;
        for(var k=0;k<ArrE.length;k++){
             Array.push(ArrE[k].label);
        }
    }
}
console.log(Array);

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.