0
//loping for objects

const users = [
    {isPremium: false},
    {isPremium: false},
    {isPremium: false},
    {isPremium: false},
    {isPremium: false},
  ]


function setUsersToPremium(users) {
  // users is an array of user objects.
  // each user object has the property 'isPremium'
  // set each user's isPremium property to true
  // return the users array
  for (let key in users) {
    users['isPremium'] = true;
  }
  return users;
}

setUsersToPremium(users);

I am true to figure out how to loop through an array of objects and change their value from false to true. My result with this code is

[true, true, true, true, true ]

but what I want to do is change each

[isPremium: true]

I'm wondering what I'm doing that is keeping me from accessing this value.

  • 1
    Also see [Why is using “for…in” with array iteration a bad idea?](https://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-a-bad-idea) – JJJ Mar 18 '18 at 07:51
  • users[key].isPremium = true – patrick Mar 18 '18 at 08:44

6 Answers6

4

You have to set as users[key].isPremium = true;

//loping for objects

const users = [
   {isPremium: false},
   {isPremium: false},
   {isPremium: false},
   {isPremium: false},
   {isPremium: false},
]


function setUsersToPremium(users) {
  for (let key in users) {
    users[key].isPremium = true;
  }
  //return users; <-- No need to return. You are changing the user variable directly with these code.
}

setUsersToPremium(users);

console.log(users);

The ideal way to do this is to use forEach instead of for/in

const users = [{isPremium: false},{isPremium: false},{isPremium: false},{isPremium: false},{isPremium: false},];

function setUsersToPremium(users) {
  users.forEach(o => o.isPremium = true);
}

setUsersToPremium(users);

console.log(users);

If you don't want to affect the original array, you can clone the object using Object.assign

const users = [{isPremium: false},{isPremium: false},{isPremium: false},{isPremium: false},{isPremium: false},];

function setUsersToPremium(users) {
  return users.map(o => {
    let x = Object.assign({}, o);
    x.isPremium = true;
    return x;
  });
}

var newUsers = setUsersToPremium(users);

console.log(newUsers);
Eddie
  • 26,593
  • 6
  • 36
  • 58
2

You are using for..in loop for an array so you'll be getting indexes of that array (1,2,3...)

To fix that you can use for..of loop

function setUsersToPremium(users) {
  for (let user of users) {
    user['isPremium'] = true;
  }
  return users;
}
mickl
  • 48,568
  • 9
  • 60
  • 89
1

You can use .map which creates a new array with your desired result.

const users = [{
    isPremium: false
  },
  {
    isPremium: false
  },
  {
    isPremium: false
  },
  {
    isPremium: false
  },
  {
    isPremium: false
  },
]

const result = users.map(o => ({ isPremium: true}))
console.log(result)
GibboK
  • 71,848
  • 143
  • 435
  • 658
0
const users = [{
  isPremium: false
}, {
  isPremium: false
}, {
  isPremium: false
}, {
  isPremium: false
}, {
  isPremium: false
}, ]
function setUsersToPremium(users) {
  // users is an array of user objects.
  // each user object has the property 'isPremium'
  // set each user's isPremium property to true
  // return the users array
  for (let key of users) {
    key.isPremium = true;
  }
  return users;
}

setUsersToPremium(users);
Mwangi Njuguna
  • 75
  • 2
  • 10
0

Here is also a simple way without using any loops. Since, you want to change the value of all the isPremium property of the objects, you can stringify the JSON array and then replace the false value with true then parse it back to an array. As simple as that:

const users = [
    {'isPremium': false},
    {'isPremium': false},
    {'isPremium': false},
    {'isPremium': false},
    {'isPremium': false},
];

var res = JSON.parse(JSON.stringify(users).replace(/false/g,'true'));

console.log(res);
Ankit Agarwal
  • 30,378
  • 5
  • 37
  • 62
  • 1
    This must be the dummest way to alter data in an object. Sorry, but this completely misses the point of what an object does... also, you really think stringify and parse work without loops? Or preg_replace? They use loops. – patrick Mar 18 '18 at 08:46
  • This elegant solution uses a technqiue that demonstrates the value of implicit iteration over manually constructing a loop. Also, the less code one writes, the less likely that human coding errors would crop up. And, the sleek code with behind the scenes iteration may have speed benefits, too. Note: serializing an object is not in itself a bad practice; see https://www.quora.com/Is-object-serialization-a-bad-practice – slevy1 Mar 18 '18 at 19:50
  • @slevy1 Of course, serialization is useful for storage or communication, but I believe that it's a bad idea to encourage using it in this specific situation. Sorry for being rude previously by the way. –  Mar 18 '18 at 22:56
  • @slevy1 Saying "elegant" is subjective. What you should better consider is the time and memory consumption of the implicit calculations involved in stringifying an object and parsing a string. I bet it's far more expensive than a good old loop. I don't have facts, but I can setup a jsperf if you like. Also, the problem with serializing/deserializing an object is that it's not the same object in memory anymore, it can be a problem, for example `===` will give `false` for references that are supposed to point to the same object. –  Mar 18 '18 at 23:03
0

const users = [
    {isPremium: false},
    {isPremium: false},
    {isPremium: false},
    {isPremium: false},
    {isPremium: false}
    ];


/** setUsersToPremium()
  * param: users, an array of objects
  * sets each user's isPremium property to true
  * returns users array
**/  
function setUsersToPremium() {
  for (let i = 0, max = users.length; i < max; i++) {
    users[i].isPremium = true;
  }
}

setUsersToPremium();
console.log(users);

A couple of notes:

  • Unnecessary to pass the users array of objects to function nor does the function need to return this array to effect desired changes.
  • Using a simple for-loop may seem old-fashioned but it still works well.
slevy1
  • 3,797
  • 2
  • 27
  • 33