Cody Dillman
Cody Dillman

Reputation: 33

How to loop through an object by using the .forEach() method and store the result in a new array

I want to loop throught the object, dogNames, and return only the names of dogs I own into the array, myDogs. I want myDogs to appear as such when logged:

['Remington','Ruby','Chief','Link']

Most likely, I'm not understanding how the .forEach() method works and/or how to manipulate objects. This is some homework help an I'm just not understanding the .forEach() method after a few hours on this. Thank you for any help. Please just point me in the right direction, I don't want other people to solve this.

First, here is the array I've written.

var dogNames = [
  {name: Kevin,     mine: false},
  {name: Remington, mine: true},
  {name: Bingo,     mine: false},
  {name: Ruger,     mine: false},
  {name: Ruby,      mine: true},
  {name: Gino,      mine: false},
  {name: Chief,     mine: true},
  {name: Watson,    mine: false},
  {name: Link,      mine: true}
];

This is the array I want to store the result to.

var myDogs = [];

This is what I've attempted to do after some google.

dogNames.forEach(function(mine){
    if(mine === true){
        myDogs.push(dogNames.name);
    }
});

Upvotes: 2

Views: 98

Answers (8)

Jolleyboy
Jolleyboy

Reputation: 1403

Instead of solving it, let's talk about 'forEach'

The argument to Array.prototype.forEach is a function. This function is called for each item in the array.

That function takes an argument representing a single item in the array. So if I have:

var results = [];
var myArray = [1, 2, 3, 4, 5];

and I have a function

function addOne(n) {
    results.push(n + 1)
}

I can call forEach on myArray like so

myArray.forEach(addOne)

And that will make my results array look like

>>> [2, 3, 4, 5, 6]

I think your confusion comes in because you're working with an array of objects, and you tried to iterate on a property of the object (mine: boolean) rather than the object itself ({name: string, mine:boolean})

In your case, you could have an array like so:

var secondResults = []
var myObjArray = [{a: 1}, {a: 2}, {a:3}]

and another function

function addOneToObj(obj) {
   obj.a = obj.a + 1;
   secondResults.push(obj)
}

you could call forEach on it

 myObjArray.forEach(addOneToObj)

and secondResults will look like

>>> [{a: 2}, {a: 3}, {a: 4}]

var results = [];
var myArray = [1, 2, 3, 4, 5];
function addOne(n) {
  results.push(n + 1)
}

myArray.forEach(addOne)
console.log(results); //[2, 3, 4, 5, 6]

var secondResults = []
var myObjArray = [{a: 1}, {a: 2}, {a:3}]
  
function addOneToObj(obj) {
   obj.a = obj.a + 1;
   secondResults.push(obj)
}

myObjArray.forEach(addOneToObj)

console.log(secondResults); //[{a: 2}, {a: 3}, {a: 4}

 

Some notes about why this is a bad approach:

Array.prototype.forEach is generally used for for side effects. Array.prototype.forEach doesn't actually return anything. If you're expecting an end result where you've changed the items in the array in some way, you should use .map instead.

That would simplify our prior example to:

    
    var myArray = [1, 2, 3, 4, 5];
    function addOne(n) {
      return n + 1
    }

    var results = myArray.map(addOne)
    console.log(results); //[2, 3, 4, 5, 6]

    
    var myObjArray = [{a: 1}, {a: 2}, {a:3}]
      
    function addOneToObj(obj) {
       obj.a = obj.a + 1;
       return (obj)
    }

    var secondResults = myObjArray.map(addOneToObj)

    console.log(secondResults); //[{a: 2}, {a: 3}, {a: 4}]

Upvotes: 0

Lucas_Santos
Lucas_Santos

Reputation: 4740

In your logic, when you do the push, you need to pass mine.name as parameter, instead of dogNames.name

And in your forEach when you put the mine, you're receiving the object like { name: 'Kevin', mine: false }, so, you need specify the propertie you'll check, like in your if statement.

var dogNames = [
  {name: 'Kevin',     mine: false},
  {name: 'Remington', mine: true},
  {name: 'Bingo',     mine: false},
  {name: 'Ruger',     mine: false},
  {name: 'Ruby',      mine: true},
  {name: 'Gino',      mine: false},
  {name: 'Chief',     mine: true},
  {name: 'Watson',    mine: false},
  {name: 'Link',      mine: true}
];

var myDogs = [];

dogNames.forEach(mine => (mine.mine && myDogs.push(mine.name)));

Upvotes: 1

Ele
Ele

Reputation: 33726

With function reduce.

var dogNames = [  {name: 'Kevin',     mine: false},  {name: 'Remington', mine: true},  {name: 'Bingo',     mine: false},  {name: 'Ruger',     mine: false},  {name: 'Ruby',      mine: true},  {name: 'Gino',      mine: false},  {name: 'Chief',     mine: true},  {name: 'Watson',    mine: false},  {name: 'Link',      mine: true}];

var myDogs = dogNames.reduce((a, d) => {
  if (d.mine) a.push(d.name);
  return a;
}, []);
console.log(myDogs);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

void
void

Reputation: 36703

In your approach:

dogNames.forEach(function(mine){
    if(mine === true){
        myDogs.push(dogNames.name);
    }
});

mine is basically a single element of the array so to access the property of that element you will need dot notation. You can use mine.mine to access the mine property and mine.name to access the name. Now just do the correct comparison and push the correct value in the array.

Though, you dont need to use .forEach(), easier approach is to use .filter() and .map() to return the value of name key from the array for mine true.

dogNames.filter(el => el.mine).map( el => el.name); 

See the full code below.

var dogNames = [
  {name: "Kevin",     mine: false},
  {name: "Remington", mine: true},
  {name: "Bingo",     mine: false},
  {name: "Ruger",     mine: false},
  {name: "Ruby",      mine: true},
  {name: "Gino",      mine: false},
  {name: "Chief",     mine: true},
  {name: "Watson",    mine: false},
  {name: "Link",      mine: true}
];

var myDogs = dogNames.filter(el => el.mine).map( el => el.name);
console.log(myDogs)

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386560

You could filter and the array and map the names of the filtered array.

var dogNames = [{ name: 'Kevin', mine: false }, { name: 'Remington', mine: true }, { name: 'Bingo', mine: false }, { name: 'Ruger', mine: false }, { name: 'Ruby', mine: true }, { name: 'Gino', mine: false }, { name: 'Chief', mine: true }, { name: 'Watson', mine: false }, { name: 'Link', mine: true }],
    myDogs = dogNames
        .filter(({ mine }) => mine)
        .map(({ name }) => name)
     
console.log(myDogs);

Upvotes: 2

Sreekanth Reddy Balne
Sreekanth Reddy Balne

Reputation: 3424

var dogNames = [
  {name: 'Kevin',     mine: false},
  {name: 'Remington', mine: true},
  {name: 'Bingo',     mine: false},
  {name: 'Ruger',     mine: false},
  {name: 'Ruby',      mine: true},
  {name: 'Gino',      mine: false},
  {name: 'Chief',     mine: true},
  {name: 'Watson',    mine: false},
  {name: 'Link',      mine: true}
];

var myDogs = [];

dogNames.forEach(function(dog){
    if(dog.mine === true){
        myDogs.push(dog.name);
    }
});

console.log(myDogs);

Upvotes: 0

NiftyAsp
NiftyAsp

Reputation: 650

When you iterate through dogNames the argument in function is each object. So what you think is mine is actually the entire object.

Instead:

dogNames.forEach(dogName => {
    if(dogName.mine === true){
        myDogs.push(dogName.name);
    }
});

Upvotes: 4

Alex Yuly
Alex Yuly

Reputation: 180

var myDogs = dogNames.filter(x => x.mine).map(x => x.name);

Upvotes: 0

Related Questions