1

I have an array which looks like this:

var arrayElements=
[
        ["1","description 1",
            [
                ["1.1","description 1.1"],
                ["1.2","description 1.2"],
                ["1.2","description 1.3"]
            ]
        ]
        ,
        ["2","description 2"],
        ["3","description 3",
            [
                ["3.1","description 3.1"],
                ["3.2","description 3.2",
                    [
                        ["3.2.1","description 3.2.1"],
                        ["3.2.2","description 3.2.2"],
                        ["3.2.2","description 3.2.3"]
                    ]
                ],
                ["3.3","description 3.3"]
            ]
        ],
        ["4","description 4"]
];

I want to loop trough the following array, be able to access all values as well as print depth of each element. Expected outcome in console would be something like this:

description 1, depth 1
description 1.1, depth 2
description 1.2, depth 2
description 1.3, depth 2
description 2, depth 1
description 3, depth 1
description 3.1, depth 2
description 3.2, depth 2
description 3.2.1, depth 3
description 3.2.2, depth 3
description 3.2.3, depth 3
description 3.3, depth 2
description 4, depth 1

Here's what I have tried:

var depth = 0;

function listNodes(array){

    for(i = 0; i < array.length;i++){
        if( /* itearating over root array */ ){
            depth = 1;
        }

        if(array[i][2] instanceof Array){
            depth++;
            console.log(array[i][1] + " depth: "+depth);
            listNodes(array[i][2]);
        }else{
            console.log(array[i][1] + " depth: "+depth);
        }
    }
}

listNodes(arrayElements);

I'm unable to loop through this array, it gets stuck even though it should continue. Another problem is the fact that my variable storing depth is not working as I'm unable to determine when the loop iterates over the root array so that I can reset the depth counter. Any ideas?

Cœur
  • 37,241
  • 25
  • 195
  • 267
jacek_podwysocki
  • 807
  • 10
  • 30

3 Answers3

1

var arrayElements=
[
        ["1","description 1",
            [
                ["1.1","description 1.1"],
                ["1.2","description 1.2"],
                ["1.2","description 1.3"]
            ]
        ]
        ,
        ["2","description 2"],
        ["3","description 3",
            [
                ["3.1","description 3.1"],
                ["3.2","description 3.2",
                    [
                        ["3.2.1","description 3.2.1"],
                        ["3.2.2","description 3.2.2"],
                        ["3.2.2","description 3.2.3"]
                    ]
                ],
                ["3.3","description 3.3"]
            ]
        ],
        ["4","description 4"]
];

function listNodes(array, depth) {
    depth = typeof depth === 'undefined' ? 1 : depth;

 var len = array.length;

    for(var i = 0; i < array.length;i++) {
        console.log(array[i][1] + " depth: "+ depth);
        
        if(array[i][2] instanceof Array) {
           listNodes(array[i][2], depth + 1);
        }
    }
}

listNodes(arrayElements);

This gives me the exact output from your example. Note that I'm passing the depth as a parameter to the function.

SVSchmidt
  • 6,269
  • 2
  • 26
  • 37
  • Thank you. Adding parameter is solution I was looking for, I was not able to come up with an idea of resetting depth counter other way than by storing it's value in variable. – jacek_podwysocki May 15 '17 at 08:38
1

It would be prettier and more flexible if you could use objects instead of remembering indexes:

var arrayElements = [{
    id: "1",
    description: "description 1",
    children: [{
      id: "1.1",
      description: "description 1.1",
      children: []
    }]
  },
  {
    id: "2",
    description: "description 2",
    children: [{
      id: "2.1",
      description: "description 2.1",
      children: [{
          id: "2.1.1",
          description: "description 2.1.1",
          children: []
        },
        {
          id: "2.1.2",
          description: "description 2.1.2",
          children: []
        }
      ]
    }]
  }
];

function deepSearch(arr, depth, cb) {
  if (depth === void 0) {
    depth = 0;
  }
  if (cb === void 0) {
    cb = function(val) {
      console.log(val);
    };
  }
  for (var i = 0; i < arr.length; i++) {
    var val = arr[i];
    cb(val.id + " - " + val.description + " at depth " + depth);
    if (val.children.length > 0) {
      deepSearch(val.children, depth + 1, cb);
    }
  }
}
deepSearch(arrayElements);
Emil S. Jørgensen
  • 6,216
  • 1
  • 15
  • 28
0

You can do something like this

function listNodes(array, depth) {
    depth++;
    for (let i = 0; i < array.length; i++) {
        console.log(array[i][1] + ' - ' + depth);
        if (typeof array[i][2] === 'object') {
            listNodes(array[i][2], depth);
        }
    }
}

listNodes(arrayElements, 0);

Considering your example o/p of this will be:

description 1 - 1
description 1.1 - 2
description 1.2 - 2
description 1.3 - 2
description 2 - 1
description 3 - 1
description 3.1 - 2
description 3.2 - 2
description 3.2.1 - 3
description 3.2.2 - 3
description 3.2.3 - 3
description 3.3 - 2
description 4 - 1
vartika
  • 494
  • 2
  • 12