1

I'm doing a code where I have to traverse a nested object and return all the values in a single string. For example, if this is the input:

var obj = {
name: "root",
contents: [
  {
    name: "A",
    contents: [
      {
        name: "fileA1",
        contents: ["Hello!"]
      }
    ]
  },
  {
    name: "B",
    contents: [
      {
        name: "dirB1",
        contents: [
          {
            name: "fileB1.1",
            contents: ["Hello!"]
          }
        ]
      }
    ]
  }
]
};

The output should be:

root
A
fileA1
Hello!
B
dirB1
fileB1.1
Hello!

My code is:

function toArray(obj) {
var result = '';
for (const prop in obj) {
    const value = obj[prop];
    if (typeof value === 'object') {
        result+=(toArray(value)); 
    }
    else {
        result+=(value);
    }
}
//console.log(result);
return result;
}

But when I run it, it returns the following string:

Hello!
fileA1undefined
undefined
Aundefined
Hello!
fileB1.1undefined
undefined
dirB1undefined
undefined
Bundefined
undefinedundefined
rootundefined

Why am I getting the "undefined" with the values and how can I fix this?

1
  • for..in with array is a bad idea may be check for that?.I have seen somewhere that using for in for array results in unpredictables values like undefined. Commented Jul 20, 2019 at 12:03

2 Answers 2

4

You could use flatMap and Object.values() like this:

var obj = {name:"root",contents:[{name:"A",contents:[{name:"fileA1",contents:["Hello!"]}]},{name:"B",contents:[{name:"dirB1",contents:[{name:"fileB1.1",contents:["Hello!"]}]}]}]}

const getValues = o =>
  Object.values(o).flatMap(v => typeof(v) === 'object' ? getValues(v) : v)

console.log(getValues(obj).join('\n'))

If you add a \n to result += value, your code returns the desired result:

function toArray(obj) {
  var result = '';
  for (const prop in obj) {
    const value = obj[prop];
    if (typeof value === 'object') {
      result += toArray(value);
    } else {
      result += value + '\n';
    }
  }
  return result;
}

var obj = {name:"root",contents:[{name:"A",contents:[{name:"fileA1",contents:["Hello!"]}]},{name:"B",contents:[{name:"dirB1",contents:[{name:"fileB1.1",contents:["Hello!"]}]}]}]}

console.log(toArray(obj))

Sign up to request clarification or add additional context in comments.

Comments

0

Running your code I get the output of

"rootAfileA1Hello!BdirB1fileB1.1Hello!"

so it is not reproducible in my browsers, however, your object has some additional members with the value of undefined. So, let's add newline and avoid undefined values:

var obj = {
name: "root",
contents: [
  {
    name: "A",
    contents: [
      {
        name: "fileA1",
        contents: ["Hello!"]
      }
    ]
  },
  {
    name: "B",
    contents: [
      {
        name: "dirB1",
        contents: [
          {
            name: "fileB1.1",
            contents: ["Hello!"]
          }
        ]
      }
    ]
  }
]
};
function toArray(obj) {
var result = '';
for (const prop in obj) {
    const value = obj[prop];
    if (typeof value === 'object') {
        result+=(toArray(value)); 
    }
    else if (value !== undefined) {
        result+=(value) + "\n";
    }
}
//console.log(result);
return result;
}
toArray(obj);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.