accessing nested objects with a for in loop

2.2k views Asked by At

Within javascript, I am trying to print the values from a few objects listed in an array in an object. The question has to do with drilling into objects/arrays with a for in loop. More specifically I'd like to avoid using a for loop if possible (I just learned for/in and am trying to understand it well)

The object looks like this:

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 : 'Jackson' },
    { first_name : 'Martin',  last_name : 'Puryear' }
  ]
};

How could i write a function that returns all of the names burried in this object? Id like to console log:

Students
1 - MICHAEL JORDAN
2 - JOHN ROSALES
3 - MARK GUILLEN
4 - KB TONEL
Instructors
1 - MICHAEL JACKSON
2 - MARTIN PURYEAR

Ive tried writing a couple for/in loops but I keep getting unexpected results. Thanks in advance for taking a look at this.

3

There are 3 answers

1
slim On BEST ANSWER

You can break a problem like this into smaller parts. First, how to we get at the individual elements of your map?

for (var key in users) {
   console.log(key);
}

logs:

students
teachers

So now we can get at the members of users one at a time, inside that loop:

var userArray = users[key];

That extracts an array each time. Now you can loop through the array, by adding this inside the loop we already have:

for(var i in userArray) {
    console.log(userArray[i]);
}

That prints out individual items from your list, e.g. {first_name: 'Michael', last_name : 'Jordan'}

Now you can print it in a different way.

 var item = userArray[i];
 console.log(i + ' ' + item[first_name] + ' ' + item[last_name]);

Put all these pieces together and you are very close to your goal (You just need to uppercase -- Google it!)

So we have everything we need to achieve in Javascript, what this pseudocode sums up:

for each type of user in "users"
   for each user record in the list
       print the index, firstname and lastname
   end
end

You can make this tidier by extracting the inner loop into a function of its own. You can do it in more advanced ways by using functional programming constructs like array.map() to translate one array into another. But the pieces above are good "beginners' way" to tackle the problem.

4
Ori Drori On

Use array#map to extract the names from the arrays:

function getNames(arr) {
  return arr.map(function(o, i) { // is the object, i is the index in the array
    return (i + 1) + ' - ' + o.first_name + ' ' + o.last_name;
  });
}

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 : 'Jackson'},
     {first_name : 'Martin', last_name : 'Puryear'}
  ]
 };

var students = getNames(users.Students);

var instructors = getNames(users.Instructors);

console.log('Students\n', students);
console.log('Instructors', instructors);

0
Mr. Polywhirl On

You can simply loop over your keys via:

for (var userGroup in users) { ... }

And you can get the list of a user's group via:

users[userGroup].forEach((item, index) => item);

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 : 'Jackson' },
    { first_name : 'Martin',  last_name : 'Puryear' }
  ]
};

createLists(users, document.body, function(user) {
  return (user.first_name + ' ' + user.last_name).toUpperCase();
});

function createLists(dataMap, target, formatFn) {
  for (var groupName in dataMap) {
    target.appendChild(createTextEl('H3', groupName));
    var listEl = document.createElement('OL');
    addListItems(dataMap[groupName], listEl, formatFn);
    target.appendChild(listEl);
  }
}
function addListItems(dataList, target, formatFn) {
  dataList.forEach((item, index) => target.appendChild(createTextEl('LI', formatFn(item))));
}
function createTextEl(tagName, text) {
  var el = document.createElement(tagName);
  el.appendChild(document.createTextNode(text));
  return el;
}
* { font-size: 0.95em; }
<link href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css" rel="stylesheet"/>