Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript - map value to keys (reverse object mapping)

I want to reverse the mapping of an object (which might have duplicate values). Example:

const city2country = {
    'Amsterdam': 'Netherlands',
    'Rotterdam': 'Netherlands',
    'Paris': 'France'
};

reverseMapping(city2country) Should output:

{
    'Netherlands': ['Amsterdam', 'Rotterdam'],
    'France': ['Paris']
}

I've come up with the following, naive solution:

const reverseMapping = (obj) => {
    const reversed = {};
    Object.keys(obj).forEach((key) => {
        reversed[obj[key]] = reversed[obj[key]] || [];
        reversed[obj[key]].push(key);
    });
    return reversed;
};

But I'm pretty sure there is a neater, shorter way, preferably prototyped so I could simply do:

const country2cities = city2country.reverse();
like image 398
Daniel Avatar asked Aug 17 '17 06:08

Daniel


People also ask

How do you reverse the key and value of an object?

invert() method of “underscore. js” to invert the key value pairs of the object. The method takes the object as a parameter and returns a copy of the object with the keys as values and values as keys.

Can you Map in reverse in JavaScript?

To reverse the order of a Map object: Use the Array. from() method to convert the Map to array. Call the reverse() method to reverse the array.

Can JavaScript Map have object as key?

By definition, a Map object holds key-value pairs where values of any type can be used as either keys or values. In addition, a Map object remembers the original insertion order of the keys. The Map() accepts an optional iterable object whose elements are key-value pairs.

How do you reverse a Map order?

To use the map() method on an array in reverse order: Use the spread syntax (...) to get a copy of the array. Use the reverse() method to reverse the copied array. Call the map() method on the reversed array.


2 Answers

You could use Object.assign, while respecting the given array of the inserted values.

const city2country = { Amsterdam: 'Netherlands', Rotterdam: 'Netherlands', Paris: 'France' };
const reverseMapping = o => Object.keys(o).reduce((r, k) =>
        Object.assign(r, { [o[k]]: (r[o[k]] || []).concat(k) }), {})

console.log(reverseMapping(city2country));
like image 87
Nina Scholz Avatar answered Oct 22 '22 09:10

Nina Scholz


There is no such built-in function in JavaScript. Your code looks fine, but given that there are so many edge cases here that could wrong, I'd suggesting using invertBy from lodash, which does exactly what you describe.

Example

var object = { 'a': 1, 'b': 2, 'c': 1 };

_.invertBy(object);
// => { '1': ['a', 'c'], '2': ['b'] }
like image 32
Lazar Ljubenović Avatar answered Oct 22 '22 11:10

Lazar Ljubenović