Swap key with value in object
Javascriptnode.jsKey ValueJavascript Problem Overview
I have an extremely large JSON object structured like this:
{A : 1, B : 2, C : 3, D : 4}
I need a function that can swap the values with keys in my object and I don't know how to do it. I would need an output like this:
{1 : A, 2 : B, 3 : C, 4 : D}
Is there any way that I can do this would manually created a new object where everything is swapped?
Thanks
Javascript Solutions
Solution 1 - Javascript
function swap(json){
var ret = {};
for(var key in json){
ret[json[key]] = key;
}
return ret;
}
Example here FIDDLE don't forget to turn on your console to see the results.
ES6 versions:
static objectFlip(obj) {
const ret = {};
Object.keys(obj).forEach(key => {
ret[obj[key]] = key;
});
return ret;
}
Or using Array.reduce() & Object.keys()
static objectFlip(obj) {
return Object.keys(obj).reduce((ret, key) => {
ret[obj[key]] = key;
return ret;
}, {});
}
Or using Array.reduce() & Object.entries()
static objectFlip(obj) {
return Object.entries(obj).reduce((ret, entry) => {
const [ key, value ] = entry;
ret[ value ] = key;
return ret;
}, {});
}
Solution 2 - Javascript
Now that we have 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'}
or:
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'}
(Updated to remove superfluous parentheses - thanks @devin-g-rhode)
Solution 3 - Javascript
you can use lodash function _.invert it also can use 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'] }
Solution 4 - Javascript
Using ES6:
const obj = { a: "aaa", b: "bbb", c: "ccc", d: "ddd" };
Object.assign({}, ...Object.entries(obj).map(([a,b]) => ({ [b]: a })))
Solution 5 - Javascript
Get the keys of the object, and then use the Array's reduce function to go through each key and set the value as the key, and the key as the value.
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);
Solution 6 - Javascript
In ES6/ES2015 you can combine use of Object.keys and reduce with the new Object.assign function, an arrow function, and a computed property name for a pretty straightforward single statement solution.
const foo = { a: 1, b: 2, c: 3 };
const bar = Object.keys(foo)
.reduce((obj, key) => Object.assign({}, obj, { [foo[key]]: key }), {});
If you're transpiling using the object spread operator (stage 3 as of writing this) that will simplify things a bit further.
const foo = { a: 1, b: 2, c: 3 };
const bar = Object.keys(foo)
.reduce((obj, key) => ({ ...obj, [foo[key]]: key }), {});
Finally, if you have Object.entries available (stage 4 as of writing), you can clean up the logic a touch more (IMO).
const foo = { a: 1, b: 2, c: 3 };
const bar = Object.entries(foo)
.reduce((obj, [key, value]) => ({ ...obj, [value]: key }), {});
Solution 7 - Javascript
2021's answer
The concise way by using ES6 syntax like this.
const obj = {A : 1, B : 2, C : 3, D : 4}
console.log(
Object.entries(obj).reduce((acc, [key, value]) => (acc[value] = key, acc), {})
);
Solution 8 - Javascript
As a complement of @joslarson and @jPO answers:
Without ES6 needed, you can use Object.keys
Array.reduce
and the Comma Operator:
Object.keys(foo).reduce((obj, key) => (obj[foo[key]] = key, obj), {});
Some may find it ugly, but it's "kinda" quicker as the reduce
doesn't spread all the properties of the obj
on each loop.
Solution 9 - Javascript
Using Ramda:
const swapKeysWithValues =
R.pipe(
R.keys,
R.reduce((obj, k) => R.assoc(source[k], k, obj), {})
);
const result = swapKeysWithValues(source);
Solution 10 - Javascript
Try
let swap = (o,r={})=> Object.keys(o).map(k=> r[o[k]]=k) && r;
let obj = {A : 1, B : 2, C : 3, D : 4};
let swap = (o,r={})=> Object.keys(o).map(k=> r[o[k]]=k) && r;
console.log(swap(obj));
Solution 11 - Javascript
I believe it's better to do this task by using an npm module, like invert-kv
.
invert-kv: Invert the key/value of an object. Example: {foo: 'bar'} → {bar: 'foo'}
https://www.npmjs.com/package/invert-kv
const invertKv = require('invert-kv');
invertKv({foo: 'bar', unicorn: 'rainbow'});
//=> {bar: 'foo', rainbow: 'unicorn'}
Solution 12 - Javascript
With pure Ramda in a pure and point-free style:
const swapKeysAndValues = R.pipe(
R.toPairs,
R.map(R.reverse),
R.fromPairs,
);
Or, with a little more convoluted ES6 version, still pure functional:
const swapKeysAndValues2 = obj => Object
.entries(obj)
.reduce((newObj, [key, value]) => ({...newObj, [value]: key}), {})
Solution 13 - Javascript
Shortest one I came up with using ES6..
const original = {
first: 1,
second: 2,
third: 3,
fourth: 4,
};
const modified = Object
.entries(original)
.reduce((all, [key, value]) => ({ ...all, [value]: key }), {});
console.log('modified result:', modified);
Solution 14 - Javascript
var data = {A : 1, B : 2, C : 3, D : 4}
var newData = {};
Object.keys(data).forEach(function(key){newData[data[key]]=key});
console.log(newData);
Solution 15 - Javascript
Here is a pure functional implementation of flipping keys
and values
in ES6:
TypeScript
const flipKeyValues = (originalObj: {[key: string]: string}): {[key: string]: string} => {
if(typeof originalObj === "object" && originalObj !== null ) {
return Object
.entries(originalObj)
.reduce((
acc: {[key: string]: string},
[key, value]: [string, string],
) => {
acc[value] = key
return acc;
}, {})
} else {
return {};
}
}
JavaScript
const flipKeyValues = (originalObj) => {
if(typeof originalObj === "object" && originalObj !== null ) {
return Object
.entries(originalObj)
.reduce((acc, [key, value]) => {
acc[value] = key
return acc;
}, {})
} else {
return {};
}
}
const obj = {foo: 'bar'} console.log("ORIGINAL: ", obj) console.log("FLIPPED: ", flipKeyValues(obj))
Solution 16 - Javascript
function swapKV(obj) {
const entrySet = Object.entries(obj);
const reversed = entrySet.map(([k, v])=>[v, k]);
const result = Object.fromEntries(reversed);
return result;
}
This can make your object, {A : 1, B : 2, C : 3, D : 4}
, array-like, so you can have
const o = {A : 1, B : 2, C : 3, D : 4}
const arrayLike = swapKV(o);
arrayLike.length = 5;
const array = Array.from(arrayLike);
array.shift(); // undefined
array; // ["A", "B", "C", "D"]
Solution 17 - Javascript
Here is an option that will swap keys with values but not lose duplicates, if your object is : { a: 1, b: 2, c: 2}, it will always return an array in the output :
function swapMap(map) {
const invertedMap = {};
for (const key in map) {
const value = map[key];
invertedMap[value] = invertedMap[value] || [];
invertedMap[value].push(key);
}
return invertedMap;
}
swapMap({a: "1", b: "2", c: "2"})
// Returns => {"1": ["a"], "2":["b", "c"]}
Solution 18 - Javascript
A simple TypeScript variant:
const reverseMap = (map: { [key: string]: string }) => {
return Object.keys(map).reduce((prev, key) => {
const value = map[key];
return { ...prev, [value]: [...(prev.value || []), key] };
}, {} as { [key: string]: [string] })
}
Usage:
const map = { "a":"1", "b":"2", "c":"2" };
const reversedMap = reverseMap(map);
console.log(reversedMap);
Prints:
{ "1":["a"], "2":["b", "c"] }
Solution 19 - Javascript
Rewriting answer of @Vaidd4, but using Object.assign
(instead of comma operator):
/**
* Swap object keys and values
* @param {Object<*>} obj
* @returns {Object<string>}
*/
function swapObject(obj) {
return Object.keys(obj).reduce((r, key) => (Object.assign(r, {
[obj[key]]: key,
})), {});
}
Or, shorter:
Object.keys(obj).reduce((r, key) => (Object.assign(r, {[obj[key]]: key})), {});
Solution 20 - Javascript
function myFunction(obj) {
return Object.keys(obj).reduce((acc, cur) => {
return { ...acc, [obj[cur]]: cur };
}, {});
}
Solution 21 - Javascript
This is the solution that I'm using:
function objSwap(obj, tl = false) {
return Object.entries(obj).reduce((a, [k, v]) => (a[v = tl ? v.toLowerCase() : v] = k = tl ? k.toLowerCase() : k, a), {});
}
As a bonus: if you need to swap then check some values I added the possibility to lowercase keys and values. Simply you've to set tl = true
, else if you don't need it ...
function objSwap(obj) {
return Object.entries(obj).reduce((a, [k, v]) => (a[v] = k, a), {});
}
Solution 22 - Javascript
Using a for...of
loop:
let obj = {A : 1, B : 2, C : 3, D : 4}
for (let [key, value] of Object.entries(obj)){
obj[value] = key
delete obj[key]
}
console.log(obj) // {1: 'A', 2: 'B', 3: 'C', 4: 'D'}