Javascript - 将值映射到键(反向对象映射)

Dan*_*iel 5 javascript ecmascript-6

我想反转对象的映射(可能有重复的值).例:

const city2country = {
    'Amsterdam': 'Netherlands',
    'Rotterdam': 'Netherlands',
    'Paris': 'France'
};
Run Code Online (Sandbox Code Playgroud)

reverseMapping(city2country) 应输出:

{
    'Netherlands': ['Amsterdam', 'Rotterdam'],
    'France': ['Paris']
}
Run Code Online (Sandbox Code Playgroud)

我想出了以下天真的解决方案:

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

但我很确定有一个更整洁,更短的方式,最好是原型,所以我可以简单地做:

const country2cities = city2country.reverse();
Run Code Online (Sandbox Code Playgroud)

谢谢.

Laz*_*vić 8

JavaScript 中没有这样的内置函数。您的代码看起来不错,但考虑到这里有很多可能出错的边缘情况,我建议使用invertByfrom lodash,它完全符合您的描述。

例子

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

_.invertBy(object);
// => { '1': ['a', 'c'], '2': ['b'] }
Run Code Online (Sandbox Code Playgroud)

  • @Daniel lodash 是模块化的,这意味着您只能安装并使用这个单一功能。在大小方面与从这里复制/粘贴功能没有太大区别,但更适合维护。只有我的两分钱。 (3认同)
  • 有人真的不赞成这个答案,因为它需要一个 3rd 方库吗?这是唯一真正满足 OP 正在寻找的答案。 (2认同)

Nin*_*olz 6

你可以使用Object.assign,同时尊重插入值的给定数组.

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));
Run Code Online (Sandbox Code Playgroud)