0

How can I use array.reduce to change the way the content of the array is. I don't want to do any math on the content.

Orinal array:

var myArray = [
    {id:1, name:'name01', value:11},
    {id:2, name:'name02', value:22},
    {id:3, name:'name03', value:33},
    {id:4, name:'name04', value:44},
    {id:5, name:'name05', value:55}
]

I want it to be changed to :

[
    {1:{id:1, name:'name01', value:11}},
    {2:{id:2, name:'name02', value:22}},
    {3:{id:3, name:'name03', value:33}},
    {4:{id:4, name:'name04', value:44}},
    {5:{id:5, name:'name05', value:55}}
]

So the id is popped out of the object as a key and the value it's the entire object.

Can this be achieved with only array.reduce without using any for loop or groupBy?

Somename
  • 3,376
  • 16
  • 42
  • 84
  • It's unusual to have a bunch of objects, each with a single, unique key. You sure that's what you need? – spanky Sep 19 '17 at 17:40
  • You could do that, but why? myArray[0].name becomes myArray[0].1.name, ugh. – James Sep 19 '17 at 17:55
  • I still dislike it, but it's easier to `dispatch` `actions` with `react-redux`. And ever since, I'm stuck on using this syntax. Am learning `array.reduce` and trying to find complex examples/answers to understand it better. Would appreciate if I you could point me to something other than the JS/Mozilla official ones. Thanks. – Somename Sep 19 '17 at 18:01

4 Answers4

6

You better use Array#map, because you need a new object for every item in the array.

var array = [{ id: 1, name: 'name01', value: 11 }, { id: 2, name: 'name02', value: 22 }, { id: 3, name: 'name03', value: 33 }, { id: 4, name: 'name04', value: 44 }, { id: 5, name: 'name05', value: 55 }],
    result = array.map(a => ({ [a.id]: a }));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

The wanted reduce style, which I do not recommend.

var array = [{ id: 1, name: 'name01', value: 11 }, { id: 2, name: 'name02', value: 22 }, { id: 3, name: 'name03', value: 33 }, { id: 4, name: 'name04', value: 44 }, { id: 5, name: 'name05', value: 55 }],
    result = array.reduce((r, a) => (r.push({ [a.id]: a }), r), []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

With concat, which I do not recommend as well.

var array = [{ id: 1, name: 'name01', value: 11 }, { id: 2, name: 'name02', value: 22 }, { id: 3, name: 'name03', value: 33 }, { id: 4, name: 'name04', value: 44 }, { id: 5, name: 'name05', value: 55 }],
    result = array.reduce((r, a) => r.concat({ [a.id]: a }), []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
2

You can use .map() instead with the ES6 calculated property name, like so:

var myArray = [
    {id:1, name:'name01', value:11},
    {id:2, name:'name02', value:22},
    {id:3, name:'name03', value:33},
    {id:4, name:'name04', value:44},
    {id:5, name:'name05', value:55}
];

var result = myArray.map((elem) => ({[elem.id]: elem}));

console.log(result);

Or if you insist on using .reduce():

var myArray = [
    {id:1, name:'name01', value:11},
    {id:2, name:'name02', value:22},
    {id:3, name:'name03', value:33},
    {id:4, name:'name04', value:44},
    {id:5, name:'name05', value:55}
];

var result = myArray.reduce((res, curr) => res.concat({[curr.id]: curr}), []);

console.log(result);

Alternatively, ES5 Syntax (for clarity since you are trying to learn)

var result = myArray.reduce(function (res, curr) {
    var newObj = {};
    newObj[curr.id] = curr;
    return res.concat(newObj);
}, []);
mhodges
  • 10,938
  • 2
  • 28
  • 46
  • This answers my curiosity .. been trying to figure out how to do this .. was not able to even form the blueprint .. thanks. This is the closest to use `reduce`. – Somename Sep 19 '17 at 17:49
  • @Somename I added ES5 syntax so you can see more clearly what is going on. The ES6 version is clean and concise, but can be a bit hard to understand what is going on if you are still learning. (and to be completely honest, even for a trained eye, the ES5 syntax is easier to look at and intuitively know what is going on) – mhodges Sep 19 '17 at 17:55
  • Thanks for the ES5 syntax .. one question. Why is the id displayed as a `string` (with quotes) when it's popped out. It's a `number`. – Somename Sep 19 '17 at 17:56
  • @Somename Do you mean the property keys? All keys are either strings or symbols. There are no number keys in JavaScript. – Sebastian Simon Sep 19 '17 at 18:00
  • I mean for 1, it's rendered as `"1"` like a string but it's actually a `number` value of the key `id`. – Somename Sep 19 '17 at 18:02
  • 1
    @Somename It depends on the console you use. Some spit it out with strings, others do not. There is no standard that determines how an object is to be spit out (unless explicitly in JSON format). Invalid property names (i.e. containing dashes, spaces, etc.) will always be wrapped as a string when output, but valid property names may not. I believe they are stored internally in the object as a string property name regardless - but someone may have to check me on that. i.e. Object.keys(obj) will always give you an array of strings or symbols - never any other type – mhodges Sep 19 '17 at 18:04
  • 1
    keys of objects are always strings. – Nina Scholz Sep 19 '17 at 18:08
1

var myArray = [
    {id:1, name:'name01', value:11},
    {id:2, name:'name02', value:22},
    {id:3, name:'name03', value:33},
    {id:4, name:'name04', value:44},
    {id:5, name:'name05', value:55}
];

let result = myArray.map(x => ({[x.id]: x }));
console.log(result)
Rick
  • 1,035
  • 10
  • 18
1

You are not reducing anything so it doesn't make sense to even try array.reduce.

You can use array.map and do this very easily.

var myArray = [
{id:1, name:'name01', value:11},
{id:2, name:'name02', value:22},
{id:3, name:'name03', value:33},
{id:4, name:'name04', value:44},
{id:5, name:'name05', value:55}
]

var newArray = myArray.map((function(val) { return { [val.id]: val }}));
console.log(newArray);
Abhinav Jain
  • 329
  • 1
  • 2
  • 9