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?

charlietfl
172k14 gold badges125 silver badges154 bronze badges
asked Jul 20, 2019 at 11:56
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))

answered Jul 20, 2019 at 12:04
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);
answered Jul 20, 2019 at 12:16

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.