'Looping in a complex JavaScript object

I have an object like this

const countries = {
  iran: {
    capital : 'Tehran',
    population  : '83183741',
    area    : '1648195'
  },
  uk: {
    capital : 'London',
    population  : '6708100',
    area    : '242495'
  },
  us: {
    capital : 'Washington D.C.',
    population  : '332641717',
    area    : '9525067'
  },
  ukraine: {
    capital : 'Kyiv',
    population  : '44983019',
    area    : '603500'
  }
};

How I can get an output like this?

iran,capital,Tehran
iran,population,83183741
iran,area,1648195
uk,capital,Tehran
uk,population,6708100
uk,area,242495
....
ukrane,capital,603500
ukrane,population,41130432
ukrane,area,603500

const countries = {
  iran: {
    capital : 'Tehran',
    population  : '83183741',
    area    : '1648195'
   
  },
  uk: {
    capital : 'London',
    population  : '6708100',
    area    : '242495'
   
  },
  us: {
    capital : 'Washington D.C.',
    population  : '332641717',
    area    : '9525067'
   
  },
  ukrane: {
    capital : 'Kiev',
    population  : '41130432 ',
    area    : '603500'
   
  }
};
  

var i = 1;
for (const country in countries) {
  console.log(country);
  for (let x in country) {
    console.log(country[x])
}
  i++
}


Solution 1:[1]

You were close. The only thing you've missed is that a for..in loop gives you the key, not the value. So, you have to access the given key on the object like this:

const countries = {
  iran: {
    capital : 'Tehran',
    population  : '83183741',
    area    : '1648195'
   
  },
  uk: {
    capital : 'London',
    population  : '6708100',
    area    : '242495'
   
  },
  us: {
    capital : 'Washington D.C.',
    population  : '332641717',
    area    : '9525067'
   
  },
  ukrane: {
    capital : 'Kiev',
    population  : '41130432 ',
    area    : '603500'
   
  }
};
  

for (const country in countries) {
  console.log(country);
  for (const property in countries[country]) {
    console.log(countries[country][property])
  }
}

From there, you can easily concatenate the pieces of information you need:

const countries = {
  iran: {
    capital : 'Tehran',
    population  : '83183741',
    area    : '1648195'
   
  },
  uk: {
    capital : 'London',
    population  : '6708100',
    area    : '242495'
   
  },
  us: {
    capital : 'Washington D.C.',
    population  : '332641717',
    area    : '9525067'
   
  },
  ukrane: {
    capital : 'Kiev',
    population  : '41130432 ',
    area    : '603500'
   
  }
};
  

for (const country in countries) {
  for (const property in countries[country]) {
    console.log(`${country},${property},${countries[country][property]}`)
  }
}

Note that for..in also iterates through key on the prototypes, so you should do extra checks to avoid this. Instead, I recommend using a for..of loop with Object.keys() or Object.entries():

const countries = {
  iran: {
    capital : 'Tehran',
    population  : '83183741',
    area    : '1648195'
   
  },
  uk: {
    capital : 'London',
    population  : '6708100',
    area    : '242495'
   
  },
  us: {
    capital : 'Washington D.C.',
    population  : '332641717',
    area    : '9525067'
   
  },
  ukrane: {
    capital : 'Kiev',
    population  : '41130432 ',
    area    : '603500'
   
  }
};
  

for (const country of Object.keys(countries)) {
  for (const property of Object.keys(countries[country])) {
    console.log(`${country},${property},${countries[country][property]}`)
  }
}

Solution 2:[2]

this can be the basic way:

//here we loop to get the countries
for (let country in countries) {
    // this will be the index (iran , uk , us , ukrane)
    
    //here we loop into the data of each country
    for(let data in countries[country]){
        //and we print the result easy as this:
        console.log(country + " , " + data + " , " +countries[country][data]);
    }

}

Solution 3:[3]

This would be another way, using Object.keys and a forEach.

const countries = {
  iran: {
    capital: 'Tehran',
    population: '83183741',
    area: '1648195'
  },
  uk: {
    capital: 'London',
    population: '6708100',
    area: '242495'
  },
  us: {
    capital: 'Washington D.C.',
    population: '332641717',
    area: '9525067'
  },
  ukrane: {
    capital: 'Kiev',
    population: '41130432 ',
    area: '603500'
  }
};

Object.keys(countries)
  .forEach(x =>
    console.log(`${x},${countries[x].capital},${countries[x].population},${countries[x].area}`)
  )

Solution 4:[4]

Maybe like this:

const countries = 
  { iran:    { capital: 'Tehran',          population: '83183741',  area: '1648195' } 
  , uk:      { capital: 'London',          population: '6708100',   area: '242495'  } 
  , us:      { capital: 'Washington D.C.', population: '332641717', area: '9525067' } 
  , ukraine: { capital: 'Kyiv',            population: '44983019',  area: '603500'  }  
  };

Object.keys(countries).forEach( cName =>
Object.entries(countries[cName]).forEach( ([k,v]) =>
  console.log( `${cName},${k},${v}`)
))
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}

Solution 5:[5]

Using nested Object.entries

const countries = {
  iran: {
    capital: "Tehran",
    population: "83183741",
    area: "1648195",
  },
  uk: {
    capital: "London",
    population: "6708100",
    area: "242495",
  },
  us: {
    capital: "Washington D.C.",
    population: "332641717",
    area: "9525067",
  },
  ukraine: {
    capital: "Kyiv",
    population: "44983019",
    area: "603500",
  },
};

Object.entries(countries).forEach(([country, obj]) =>
  Object.entries(obj).forEach(([key, value]) =>
    console.log([country, key, value].join())
  )
);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Frank Yohan Rodríguez Pérez
Solution 3 BeRT2me
Solution 4 halfer
Solution 5 Siva K V