0

I want to assign a property to an object, that is part of an array of objects. The value shall be the value of an existing property of the object. How is this done?

    const data = [ {id: 111, name: 'AAA'}, ...];

    const result= data.map(item => {
      item.copyOfId= item.id;
      return item;
    });
vuvu
  • 4,886
  • 12
  • 50
  • 73

3 Answers3

4

There's no need for map there, you just need to loop through the array, not map the array. So all the usual ways of looping through arrays apply, such as forEach:

const data = [ {id: 111, name: 'AAA'}, ...];
data.forEach(item => {
  item.copyOfId = item.id;
});

or for-of:

const data = [ {id: 111, name: 'AAA'}, ...];
for (const item of data) {
  item.copyOfId = item.id;
}

As Mörre points out in a comment, in functional programming map is indeed what you would reach for, but usually you'd create new objects to populate the new array, instead of modifying (mutating) the objects:

const data = [ {id: 111, name: 'AAA'}, ...];
const result = data.map(item => {
  return {...item, copyOfId: item.id};
});

(That example uses spread properties, which are only a Stage 3 proposal but are supported by up-to-date Chrome and Firefox. You could use Object.assign instead. Either way, it's a shallow copy if that's important.)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    To elaborate on the `map`, it would be fine - IF he produced a completely new array (functional programming style, no mutations, etc.). But producing a new array while still mutating the content items - that's a conflicting message. Either all new (use `map`), or mutate (use `forEach`). Note that sure, you can use either one, it's just that there are certain associations/assumptions associated with those methods, which come from other languages. – Mörre Nov 28 '17 at 16:03
  • @cale_b: `for-of`, arrow functions, and `const` are, `forEach` isn't. I'd say the question doesn't relate to ES2015 ("ES6") *specifically*, so probably not. – T.J. Crowder Nov 28 '17 at 16:05
  • 1
    @T.J.Crowder sorry, the index was wrong and i now corrected in the question, thanks for the fast answer – vuvu Nov 28 '17 at 16:08
3

A slightly different and shorter version (using object destructuring) would look like so:

const data = [ {id: 111, name: 'AAA'}, ...];

const result = data.map(({ id, name }) => ({ id, name, copyOfId: id }));

And using spread syntax:

const result = data.map(item => ({ ...item, copyOfId: item.id }));

Previous solutions work just as well, but I thought you may be interested in some additional ES2015 features.

Gorka Hernandez
  • 3,890
  • 23
  • 29
2

You can use map and within each iteration, you can use the spread operator to create a duplicate BUT new object.

const data = [{
  id: 111,
  name: 'AAA'
}];

const result = data.map((item) => {      
  return { ...item, copyOfId: item.id };
});

console.log(result);
Carl Edwards
  • 13,826
  • 11
  • 57
  • 119
  • Why? Doesn't he want a new array of objects? – Carl Edwards Nov 28 '17 at 16:04
  • 1
    Even if OP wanted new array of objects your answer is still wrong because it will produce new array of ids. – dfsq Nov 28 '17 at 16:05
  • Where am I mutating the array though? Is this not pure? – Carl Edwards Nov 28 '17 at 16:08
  • 1
    You mutate the items in the array. Which still are the same ones in the old array, because those are object references. _EDIT: Before the edit._ – Mörre Nov 28 '17 at 16:09
  • @CarlEdwards - For what it's worth, I enjoy participating in SO (including answering) because I'm always learning from people way smarter than me. So don't be discouraged by these comments - they are an invaluable education (which I'm learning from!) – random_user_name Nov 28 '17 at 16:15
  • @cale_b It's all good. I feel the same way on learning from the best. I think in this case I just jumped the gun a bit when submitting. – Carl Edwards Nov 28 '17 at 16:19