3

I'd like to know if one can use .map() to dynamically change the added value to JS objects.

For example, a static use of .map() allows to add a similar ID to all objects of the array.

friends = [
          {
            "age": 10,
            "name": "Castillo"
          },
          {
            "age": 11,
            "name": "Daugherty"
          },
          {
            "age": 12,
            "name": "Travis"
          }
        ]

// Static mapping --> adds 1 to all objects
friends_static=friends;
friends.map(elem => elem["id"] = 1);
console.log(friends_static)

This returns [{age=10, name="Castillo", id=1}, {age=11, name="Daugherty", id=1}, {age=12, name="Travis", id=1}]

Is it possible to add a unique ID which increments by 1 for each object in a similar way?

Cf. the illustrative JSfiddle and example code below. I know the 1++ is not legal, but just shows the idea I'm trying to realize.

//Dynamic mapping? --> should add 1,2,3...to objects incrementally
/*
friends_dynamic=friends;
friends.map(elem => elem["id"] = 1++);
console.log(friends_dynamic)
*/

This should return [{age=10, name="Castillo", id=1}, {age=11, name="Daugherty", id=2}, {age=12, name="Travis", id=3}]

1
  • Why .map() specifically? That's used for creating a new array, but you don't seem to want one. Commented Dec 20, 2017 at 13:54

4 Answers 4

18

You could just use the index provided to the Array#map callback:

friends.map((friend, index) => Object.assign({}, friend, { id: index + 1 }))

It's not a good idea to mutate objects in Array#map. The whole purpose of the method is to return new objects that are mapped from the original objects. Thus use Object.assign to avoid mutation.

Of course, if you wanted mutation, thus just use forEach without mapping to new values. It would be more "semantically correct" in that case.

Sign up to request clarification or add additional context in comments.

1 Comment

So .forEach() seems like a good solution for mutating the existing objects in the array, as the OP has requested, right?
8

Is this what you mean?

const friends = [
    {
        "age": 10,
        "name": "Castillo"
    },
    {
        "age": 11,
        "name": "Daugherty"
    },
    {
        "age": 12,
        "name": "Travis"
    }
]

friends.forEach((friend, index) => friend.id = index + 1);

console.log(friends)

5 Comments

Yes, whilst you could use map to achieve the same result, it would be really confusing to do so, as the semantics of map() suggest you're creating something new from something else. If I see forEach(), I'm prepared for a mutation such as this.
Thanks for the light @blaz @Ian! The reason I went for .map() is that I assumed it would be the quickest/most efficient approach. Could you confirm that this forEach() approach is at least equivalent in terms of speed for a larger object? Furthermore, bonus question if you wouldn't mind: how could I make sure the ids are added to objects not randomly but ordered based on another value (e.g. increasing age values (assuming all ages are unique))?
@sc28: Curious why you thought .map() would be most efficient. Does it have anything to do with a blog post?
With absolutely no data to back this up, .map() seems like it would be less efficient as you're also creating an array of n elements which will presumably just be undefined
@rock it was rather based on an unfounded hunch actually. I think read that the arrow-notation was a recent feature from ES6, so I inferred it would be a "modern", and so efficient approach. This post actually seems to indicate that map would be slower then alternatives, so debunking my hunch.
2

if you only need an incremental value from 0 on, you can simply use a counter and increment it, like this:

let id = 1;
friends.map(elem => {elem.id = id++;});

Comments

2

Use a local variable and increment it. As per method definition "The map() method calls the provided function once for each element in an array, in order". In Order would make sure that ids do not collide.

friends = [
      {
        "age": 10,
        "name": "Castillo"
      },
      {
        "age": 11,
        "name": "Daugherty"
      },
      {
        "age": 12,
        "name": "Travis"
      }
    ]

// Static mapping --> adds 1 to all objects
friends_static=friends;
var i = 1;
friends_static.map(elem => elem["id"] = i++);
console.log(friends_static)

//Dynamic mapping? --> should add 1,2,3...to objects incrementally
/*
friends_dynamic=friends;
friends_dynamic.map(elem => elem["id"] = 1++);
console.log(friends_dynamic)
*/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.