2

I'd like to convert an array into an object using one of the properties as key.

For instance:

var stations = [ { name: 'A Coruna', ds100: 'OECSC' }, ... ];

I'd like to get stationByDs100:

{ 'OECSC': { name: 'A Coruna', ds100: 'OECSC' }, ... }

At the moment I do it as follows:

var stationByDs100 = {};
stations.forEach(station => stationByDs100[station.ds100] = station);

I'm looking for a better way to accomplish this - is it possible with a one-liner without explicit variable declaration?

For instance in Java 8 this could have accomplished with streams and collectors in one line like:

Map<String, Station> stationByDs100 = stations.stream()
    .collect(toMap(Station::getDs100, identity()));

So I was thinking maybe there's a similar way in JS.

I'm using Node.js so OK to use the latest JS/ES features Node.js supports.

I've browsed through a rougly dozen existing answers but they mostly use older JS/ES versions and suggest even longer solutions.

5
  • 1
    Use Array.prototype.reduce, see MDN for examples. Commented Jan 29, 2017 at 10:11
  • @SpencerWieczorek One-liner, without explicit variable declaration, from said criteria it is better. Commented Jan 29, 2017 at 10:17
  • Is there a specific purpose for wanting the code to be a one-liner? Usually one-line code, especially involving functional-style array methods, are slower than the equivalent code using for/while loops and more than one line of code Commented Jan 29, 2017 at 10:19
  • 1
    @Zorgatone No technical reason. I don't care about performance in this case and wanted to learn more about functional style in JS as I'm quite weak in that. Commented Jan 29, 2017 at 10:21
  • Ok, makes sense Commented Jan 29, 2017 at 10:22

2 Answers 2

9

You could use Object.assign with computed property names.

var stations = [ { name: 'A Coruna', ds100: 'OECSC' }],
    object = stations.reduce((o, a) => Object.assign(o, { [a.ds100]: a }), {});

console.log(object);

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

3 Comments

I would prefer Object.assign({}, o, { [a.ds100]: a }) instead of Object.assign(o, { [a.ds100]: a }) to prevent side effects. just a personally preference.
the difference is, i return the same object, while NonPolynomial suggest to use a new object all time.
@NinaScholz Yes, I got it, thank you. I think it's not really necessary in this case as accumulator object is only used in reduction.
0

Object.fromEntries can help with this:

const stations = [{ name: 'Berlin Südkreuz', ds100: 'BPAF' }, { name: 'Berg', ds100: 'KBEG' }];
const object = Object.fromEntries(stations.map(o => [o.ds100, o]));
console.log(object);

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.