使用值JSON交换密钥

C1D*_*C1D 85 javascript json key-value node.js

我有一个非常大的JSON对象,结构如下:

{A : 1, B : 2, C : 3, D : 4}
Run Code Online (Sandbox Code Playgroud)

我需要一个可以用我的对象中的键交换值的函数,我不知道该怎么做.我需要这样的输出:

{1 : A, 2 : B, 3 : C, 4 : D}
Run Code Online (Sandbox Code Playgroud)

我有什么方法可以手动创建一个交换所有内容的新对象?
谢谢

jPO*_*jPO 92

function swap(json){
  var ret = {};
  for(var key in json){
    ret[json[key]] = key;
  }
  return ret;
}
Run Code Online (Sandbox Code Playgroud)

这里的例子FIDDLE不要忘记打开你的控制台来查看结果.


Oha*_*dan 35

你可以使用lodash函数_.invert它也可以使用multivlaue

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

  _.invert(object);
  // => { '1': 'c', '2': 'b' }

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


Pat*_*ans 33

获取对象的键,然后使用Array的reduce函数遍历每个键并将值设置为键,将键设置为值.

var data = {A : 1, B : 2, C : 3, D : 4}
var newData = Object.keys(data).reduce(function(obj,key){
   obj[ data[key] ] = key;
   return obj;
},{});
console.log(newData);
Run Code Online (Sandbox Code Playgroud)


小智 29

使用ES6:

const obj = { a: "aaa", b: "bbb", c: "ccc", d: "ddd" };
Object.assign({}, ...Object.entries(obj).map(([a,b]) => ({ [b]: a })))
Run Code Online (Sandbox Code Playgroud)

  • 现在看来**更好的解决方案**(2019 年)!有人可以确认,是吗?性能好吗?语义是完美的:我们可以看到这确实是一个简单的“映射和交换”解决方案。 (3认同)
  • @peter-krauss,欢迎您修改 http://jsben.ch/gHEtn,以防我遗漏了什么,但是这个答案和 jPO 的答案之间的随意比较表明 jPO 的 for 循环比 grappeq 的 map 方法的性能高出近 3 到1(至少在 _my_ 浏览器上)。 (2认同)

jos*_*son 28

在ES6/ES2015中,您可以结合使用Object.keys并使用新的Object.assign函数,箭头函数计算属性名称进行简化,以获得非常简单的单一语句解决方案.

const foo = { a: 1, b: 2, c: 3 };
const bar = Object.keys(foo)
    .reduce((obj, key) => Object.assign({}, obj, { [foo[key]]: key }), {});
Run Code Online (Sandbox Code Playgroud)

如果您正在使用对象扩展运算符进行转换(编写此脚本时的第3阶段),这将进一步简化操作.

const foo = { a: 1, b: 2, c: 3 };
const bar = Object.keys(foo)
    .reduce((obj, key) => ({ ...obj, [foo[key]]: key }), {});
Run Code Online (Sandbox Code Playgroud)

最后,如果你有Object.entries可用(写作时的第4阶段),你可以更多地清理逻辑(IMO).

const foo = { a: 1, b: 2, c: 3 };
const bar = Object.entries(foo)
    .reduce((obj, [key, value]) => ({ ...obj, [value]: key }), {});
Run Code Online (Sandbox Code Playgroud)


Sc0*_*tyD 10

Now that we have Object.fromEntries:

obj => Object.fromEntries(Object.entries(obj).map(a => a.reverse()))
Run Code Online (Sandbox Code Playgroud)

or

obj => Object.fromEntries(Object.entries(obj).map(([k, v]) => ([v, k])))
Run Code Online (Sandbox Code Playgroud)


Ngu*_*ong 7

2021年的答案

像这样使用ES6语法的简洁方式。

const obj = {A : 1, B : 2, C : 3, D : 4}

console.log(
  Object.entries(obj).reduce((acc, [key, value]) => (acc[value] = key, acc), {})
);
Run Code Online (Sandbox Code Playgroud)


小智 5

作为 @joslarson 和 @jPO 答案的补充:
无需 ES6,您可以使用和逗号运算符Object.keys Array.reduce

Object.keys(foo).reduce((obj, key) => (obj[foo[key]] = key, obj), {});
Run Code Online (Sandbox Code Playgroud)

有些人可能会觉得它很难看,但它“有点”更快,因为它reduce不会在每个循环上传播所有属性obj