我有一个非常大的JSON对象,其结构如下:
{A : 1, B : 2, C : 3, D : 4}
我需要一个函数,可以交换我的对象中的键和值,但我不知道如何做。我需要的输出应该是这样的:
{1 : A, 2 : B, 3 : C, 4 : D}
有没有办法我可以手动创建一个新对象,其中所有内容都被交换?
谢谢
我有一个非常大的JSON对象,其结构如下:
{A : 1, B : 2, C : 3, D : 4}
我需要一个函数,可以交换我的对象中的键和值,但我不知道如何做。我需要的输出应该是这样的:
{1 : A, 2 : B, 3 : C, 4 : D}
有没有办法我可以手动创建一个新对象,其中所有内容都被交换?
谢谢
function swap(json){
var ret = {};
for(var key in json){
ret[json[key]] = key;
}
return ret;
}
这里有个例子FIDDLE,别忘了打开控制台查看结果。
ES6 版本:
static objectFlip(obj) {
const ret = {};
Object.keys(obj).forEach(key => {
ret[obj[key]] = key;
});
return ret;
}
或者使用Array.reduce()和Object.keys()方法
static objectFlip(obj) {
return Object.keys(obj).reduce((ret, key) => {
ret[obj[key]] = key;
return ret;
}, {});
}
或者使用Array.reduce() 和 Object.entries()
static objectFlip(obj) {
return Object.entries(obj).reduce((ret, entry) => {
const [ key, value ] = entry;
ret[ value ] = key;
return ret;
}, {});
}
Object.keys()
+ Array.prototype.reduce()
是最快的:https://jsbench.me/y2kzww53oz/1 - Amit Beckenstein现在我们有了Object.fromEntries:
const f = obj => Object.fromEntries(Object.entries(obj).map(a => a.reverse()))
console.log(
f({A : 'a', B : 'b', C : 'c'})
) // => {a : 'A', b : 'B', c : 'C'}
const f = obj => Object.fromEntries(Object.entries(obj).map(([k, v]) => [v, k]))
console.log(
f({A : 'a', B : 'b', C : 'c'})
) // => {a : 'A', b : 'B', c : 'C'}
(已更新,删除了多余的括号 - 感谢@devin-g-rhode)
Object.entries()
+ Array.prototype.reduce()
稍慢一些:https://jsbench.me/y2kzww53oz/1 - Amit Beckenstein你可以使用 lodash函数_.invert,它也可以使用多个值
var object = { 'a': 1, 'b': 2, 'c': 1 };
_.invert(object);
// => { '1': 'c', '2': 'b' }
// with `multiValue`
_.invert(object, true);
// => { '1': ['a', 'c'], '2': ['b'] }
_.invertBy()
来替代将 multiValue
设置为 true
。 - white_gecko使用 ES6:
const obj = { a: "aaa", b: "bbb", c: "ccc", d: "ddd" };
Object.assign({}, ...Object.entries(obj).map(([a,b]) => ({ [b]: a })))
获取对象的键,然后使用数组的reduce函数遍历每个键,并将值设置为键,键设置为值。
const data = {
A: 1,
B: 2,
C: 3,
D: 4
}
const newData = Object.keys(data).reduce(function(obj, key) {
obj[data[key]] = key;
return obj;
}, {});
console.log(newData);
const foo = { a: 1, b: 2, c: 3 };
const bar = Object.keys(foo)
.reduce((obj, key) => Object.assign({}, obj, { [foo[key]]: key }), {});
const foo = { a: 1, b: 2, c: 3 };
const bar = Object.keys(foo)
.reduce((obj, key) => ({ ...obj, [foo[key]]: key }), {});
最后,如果您可以使用Object.entries(截至撰写本文为止已达到第4阶段),则可以使逻辑更加简洁。
const foo = { a: 1, b: 2, c: 3 };
const bar = Object.entries(foo)
.reduce((obj, [key, value]) => ({ ...obj, [value]: key }), {});
53 | .reduce((obj, [key, value]) => ({...obj, [value]: key}), {}); | ^- Superlokkus
通过使用像这样的ES6语法来简洁地表达。
const obj = {A : 1, B : 2, C : 3, D : 4}
console.log(
Object.entries(obj).reduce((acc, [key, value]) => (acc[value] = key, acc), {})
);
说明:
(acc[value] = key, acc)
使用逗号运算符(,)语法。
逗号运算符(,)
从左到右依次计算并返回最后一个表达式的值。
Object.keys
、Array.reduce
和 逗号运算符:Object.keys(foo).reduce((obj, key) => (obj[foo[key]] = key, obj), {});
有些人可能会觉得它很丑,但这种方式比较快,因为reduce
不会在每次循环中展开obj
的所有属性。
forEach
、map
或reduce
方法更快。
我提供了这个解决方案,以便不需要es6也能有一行代码的解决方案,并且在速度和效率方面仍然是相关的。 - Vaidd4使用Ramda:
const swapKeysWithValues =
R.pipe(
R.keys,
R.reduce((obj, k) => R.assoc(source[k], k, obj), {})
);
const result = swapKeysWithValues(source);
R.invert
和R.invertObj
,它们的作用是一样的。第一个函数将重复值放在子列表中。 - kidrocaconst swapKeyValue = (object) =>
Object.entries(object).reduce((swapped, [key, value]) => (
{ ...swapped, [value]: key }
), {});
type ValidKey = number | string;
const swapKeyValue = <K extends ValidKey, V extends ValidKey>(
object: Record<K, V>
): Record<V, K> =>
Object.entries(object)
.reduce((swapped, [key, value]) => (
{ ...swapped, [value as ValidKey]: key }
), {} as Record<V, K>);
function swap(obj) {return new Map(Object.entries(x).map([k, v] => [v, k]))}
- broofa