2
\$\begingroup\$

I have an object that has an array inside with another object inside. I iterate over the object and array to print out the first name and last name of the people inside the array of objects. I am wondering if there is a better way to do this. Without having to use obj[i].first_name + " " + obj[i].last_name

Here is my code

    var users = {
 'Students': [ 
     {first_name:  'Michael', last_name : 'Jordan'},
     {first_name : 'John', last_name : 'Rosales'},
     {first_name : 'Mark', last_name : 'Guillen'},
     {first_name : 'KB', last_name : 'Tonel'}
  ],
 'Instructors': [
     {first_name : 'Michael', last_name : 'Choi'},
     {first_name : 'Martin', last_name : 'Puryear'}
  ]
 }
    for(item in users)
    {
        console.log(item);
        var obj = users[item]
        for(var i = 0; i < obj.length; i++)
        {
            var obj2 = obj[i];
      var name = "";
            for(j in obj2)
            {
          name += obj2[j] + " ";
            }
      console.log(name);
      name ="";
        }
    }
\$\endgroup\$
  • \$\begingroup\$ What do you think is wrong with obj[i].first_name + " " + obj[i].last_name? \$\endgroup\$ – 200_success Jan 30 '17 at 5:10
4
\$\begingroup\$

To directly answer your question, yes, there is a better way: template literals and using array methods.

In the following snippet, it uses Object.keys and array.reduce to concatenate all arrays in the object into one array, array.map to generate an array of name strings from that array, and array.forEach to ultimately loop through the names array and print names.

const users = {
  'Students': [ 
    {first_name:  'Michael', last_name : 'Jordan'},
    {first_name : 'John', last_name : 'Rosales'},
    {first_name : 'Mark', last_name : 'Guillen'},
    {first_name : 'KB', last_name : 'Tonel'}
  ],
  'Instructors': [
    {first_name : 'Michael', last_name : 'Choi'},
    {first_name : 'Martin', last_name : 'Puryear'}
  ]
}

Object.keys(users)
  .reduce((names, userType) => names.concat(users[userType]), [])
  .map(userObject => `${userObject.first_name} ${userObject.last_name}`)
  .forEach(name => console.log(name));

If you're not into ES6, here's the ES5 equivalent:

const users = {
  'Students': [ 
    {first_name:  'Michael', last_name : 'Jordan'},
    {first_name : 'John', last_name : 'Rosales'},
    {first_name : 'Mark', last_name : 'Guillen'},
    {first_name : 'KB', last_name : 'Tonel'}
  ],
  'Instructors': [
    {first_name : 'Michael', last_name : 'Choi'},
    {first_name : 'Martin', last_name : 'Puryear'}
  ]
}

Object.keys(users)
  .reduce(function(names, userType) {
    return names.concat(users[userType]);
  }, [])
  .map(function(userObject) {
    return ((userObject.first_name) + " " + (userObject.last_name));
  })
  .forEach(function(name) {
    return console.log(name);
  });

As for your code:

  • Indentation needs to be more consistent.
  • Names in JS follow the camelCase convention.
  • Most of JS code I've seen use the "egyptian braces" (collapsed braces).
  • Note that variables declared with var is function-scoped. Loops don't scope vars locally.
  • for-in loops should be guarded with an object.hasOwnProperty check.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.