Reputation: 39
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.
Upvotes: 0
Views: 85
Reputation: 2584
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/
Upvotes: 0
Reputation: 2310
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.");
Upvotes: 0
Reputation: 48
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.
Upvotes: 2
Reputation: 7013
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"));
Upvotes: 0
Reputation: 756
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.
Upvotes: 2