0

In the following code, I have an array which contains objects which each contain another object. I'd like to do a for loop which targets one of the elements inside the innermost object.

var myArray = [
    {nemo : {type: "fish", scales: "yes"}}, 
    {bubbles : {type: "fish", scales: "yes"}}, 
    {jimmy : {type: "turtle", scales: "no"}}
];
function findType (array, animalType) {
    var newArray = [];
    for (i = 0; i < array.length; i ++){
        if (array[i][*what goes here?*].type == animalType){
            newArray.push(array[i]);
        }
    }
        return newArray;
}
findType(myArray, "fish");

The problem I'm having is to get down to the level I want the names of the fish (i.e. nemo, bubbles) would need to be known in each loop of the for loop, and these names are different each time. What would be a way to go down past this level into the object that I want? Thank you.

Mohit Tanwani
  • 6,608
  • 2
  • 14
  • 32
  • I don't quite follow.. What do you want the result of `findType(myArray, "fish")` to be in the above case? – James Aug 23 '16 at 14:08
  • 1
    Maybe you're looking for the `in` operator? `for (var i=0; i – Eric Dobbs Aug 23 '16 at 14:08
  • I was hoping that it would push the objects which contain the type of fish into a new array called newArray. – Jonathan Foster Aug 23 '16 at 14:11
  • Possible duplicate of [Access / process (nested) objects, arrays or JSON](http://stackoverflow.com/questions/11922383/access-process-nested-objects-arrays-or-json) – Teemu Aug 23 '16 at 14:11
  • 1
    This doesn't answer your question but if you could change your data structure, I would recommend moving the names inside the innermost object, and only having an array of objects `[{name: "nemo", type: "fish", scales: "yes}, {"name": "jimmy", ...}, ...]` – Damián Castro Aug 23 '16 at 14:16
  • 1
    Thank you very much everyone, already got great answers that I was looking for in 5 short minutes. Yeah, the data structure was a hypothetical I was just after getting the answer to this concept that I couldn't grasp, and I did! Thank you!! – Jonathan Foster Aug 23 '16 at 14:21
  • @JonathanFoster if the data structure is just an example, I advise you to take Damián's recommendation. Object keys are meant to be known by your program, but the values of the keys are not. – Mulan Oct 13 '16 at 03:51

5 Answers5

2

I'd recommend restructuring the code a bit, as well as your objects. Instead, of having the name point to an object, e.g. {nemo : {type: "fish", scales: "yes"}}, have the name be a property on its own. So, change this to: {name: "nemo", type: "fish", scales: "yes"} Not only does this make accessing each property easier, it'll make your code much clearer.

This way, your code becomes:

var myArray = [{name: "nemo",type: "fish", scales: "yes"}, 
 {name: "bubbles",type: "fish", scales: "yes"}, 
 {name: "jimmy",type: "turtle", scales: "no"}];


 function findType (array, animalType) {
  var newArray = [];
  for (i = 0; i < array.length; i ++){
    if (array[i].type == animalType){
       newArray.push(array[i]);
    }
     return newArray;
   }

  findType(myArray, "fish");

If you can't restructure the fish objects, others have provided answers that address your question without restructuring the objects.

Ted
  • 746
  • 1
  • 7
  • 19
  • Thank you, I agree...the data structure is not one I'm using in a real application. I posted it as a hypothetical in order to get the answer to this concept that I couldn't figure out. – Jonathan Foster Aug 23 '16 at 14:27
2

You can get the list of an object's attributes with Object.keys()

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

In your case you can do:

    if (array[i][Object.keys(array[i])[0]].type == animalType){

    //you can see it like this for the first fish :
    //array[i] ---> {nemo : {type: "fish", scales: "yes"}}
    //Object.keys(array[i]) ---> ["nemo"]
    //array[i]["nemo"] ---> {type: "fish", scales: "yes"}

But I agree with the others that you may consider changing your data structure.

Robin D.
  • 48
  • 5
0

You can traverse through object key values using for ... in, then checking for hasOwnProperty ensures its your defined key values.

Then for each of those you can check for type.

function findType (array, animalType) {
    var newArray = [];
    for (i = 0; i < array.length; i ++){
        for (var key in array[i]) {
            if( array[i].hasOwnProperty(key) ) {
                if(array[i][key].type === animalType) {
                   newArray.push(array[i]);
                }
            } 
        }  
    }
    return newArray;
}

Here is working jsfiddle: https://jsfiddle.net/9kt64d21/

Arathi Sreekumar
  • 2,544
  • 1
  • 17
  • 28
  • @Bill Doughty: I had already updated code to remove p. Please check again. There is no p in there. Anyway I had explained the answer too, so I don't see a reason for down voting. – Arathi Sreekumar Aug 23 '16 at 14:25
  • nothing personal. You know how SO is. When I loaded the page, your code was invalid. Answers with code should have working code. I didn't see you had updated it when I down voted. That's all. I removed my down vote since you fixed it. – Bill Doughty Aug 23 '16 at 14:38
  • No probs. I did notice I forgot to change the variable name and had fixed it immediately. I thought you were the OP initially and couldn't get my answer working. – Arathi Sreekumar Aug 23 '16 at 14:40
0

try with double loop

var myArray = [{nemo : {type: "fish", scales: "yes"}}, 
{bubbles : {type: "fish", scales: "yes"}}, 
{jimmy : {type: "turtle", scales: "no"}}];


function findType (array, animalType) {
     var newArray = [];
     for (i = 0; i < array.length; i ++){
            for(var name in array[i]){
               if(array[i][name].type == animalType){
                   newArray.push(array[i]);
            }
         }
     }
     return newArray;
};

console.log(findType(myArray, "fish"));

fiddle link

Özgür Ersil
  • 6,909
  • 3
  • 19
  • 29
0

Use for <key> in <object>:

var myArray = [{nemo : {type: "fish", scales: "yes"}}, 
{bubbles : {type: "fish", scales: "yes"}}, 
{jimmy : {type: "turtle", scales: "no"}}];


function findType (array, animalType) {
  var newArray = [];
  for (i = 0; i < array.length; i ++){
    var animal = array[i];
    for (var key in animal) {
      var description = animal[key];
      if( description.type == animalType ) {
        console.log("" + key + " is a " + animalType);
        newArray.push(array[i]);
      } 
    }  
  }
  return newArray;
}

var fish = findType(myArray, "fish");
console.log("" + fish.length + " fish found.");
Bill Doughty
  • 2,250
  • 14
  • 20