1

I am trying to get all the values of the nested object by BFS: This is the sample object:

let schedule =
{
  date: '0305',
  meeting1: {
    id: '00001',
    start: '10:30'
  },
  meeting2: {
    id: '00002',
    start: '12:30'
  }
}

Ideal output:

['0305', '00001', '10:30', '00002', '12:30']

My attempt:

function getNestedObjValuesByQueue(obj){
  let queue = [obj]
  let values = []
  while (queue.length > 0){
    let current = queue.shift();
    console.log(current);
    values = values.concat(Object.keys(current));
    for (let key of Object.values(current)){
      queue.push(key)
    }
  }
  // console.log(values)
}
getNestedObjValuesByQueue(schedule)

Well when I tried to log current there comes infinite loop:

5
0
0
0
0
1
1
0
:
3
0
0
0
0
0
2
1
2
:
3
0
0
3
0
5
0
0
0
0
1
1
0
:

Still have no idea what is going on here... Can anyone help me out? Thanks in advance.

Housoul
  • 91
  • 1
  • 2
  • 9
  • Does this answer your question? [how to print all values of a nested object](https://stackoverflow.com/questions/29516136/how-to-print-all-values-of-a-nested-object) – Heretic Monkey Mar 03 '21 at 22:04
  • 1
    Your while loop never exits because it's predicated on `queue.length`, which you get one item out of via `queue.shift()` but then add a bunch of items in that never get removed via `queue.push(key)`. So unless `obj` has no enumerable properties `queue` will never be empty once you enter the loop. – ray Mar 03 '21 at 22:04
  • @Heretic Thanks, but I am really curious about how to collect values iteratively... lol – Housoul Mar 03 '21 at 22:29
  • So... instead of `console.log` use `array.push`. – Heretic Monkey Mar 03 '21 at 22:31

2 Answers2

1

I don't think a while loop is the right approach here. For the general case, you'll need a recursive function. When encountering an object, push it to a different queue. At the end, after iterating over one depth, call the function again recursively with the new queue if there are any items in it.

let schedule =
{
  date: '0305',
  meeting1: {
    id: '00001',
    start: '10:30'
  },
  meeting2: {
    id: '00002',
    start: '12:30'
  }
}
function getNestedObjValuesByQueue(queue, values = []){
  const nextQueue = [];
  for (const item of queue) {
    for (const val of Object.values(item)) {
      if (val && typeof val === 'object') {
        nextQueue.push(val);
      } else {
        values.push(val);
      }
    }
  }
  if (nextQueue.length) {
    getNestedObjValuesByQueue(nextQueue, values);
  }
  return values;
}
console.log(getNestedObjValuesByQueue([schedule]))
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
1

At each iteration in the while-loop, when iterating over the values of current, if it's an object push it to the queue, otherwise, save it in values:

const schedule = {
  date: '0305',
  meeting1: {
    id: '00001',
    start: '10:30'
  },
  meeting2: {
    id: '00002',
    start: '12:30'
  }
};

function getNestedObjValuesByQueue(obj){
  let queue = [obj]
  let values = []
  while (queue.length > 0){
    let current = queue.shift();
    for (let val of Object.values(current)){
      if(typeof val === "object") queue.push(val);
      else values.push(val);
    }
  }
  console.log(values)
}

getNestedObjValuesByQueue(schedule)
Majed Badawi
  • 27,616
  • 4
  • 25
  • 48