web-dev-qa-db-ja.com

値がJSONのキーを交換する

次のような構造の非常に大きなJSONオブジェクトがあります。

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

オブジェクト内のキーと値を交換できる関数が必要で、その方法がわかりません。次のような出力が必要です。

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

すべてを交換する新しいオブジェクトを手動で作成する方法はありますか?
ありがとう

75
C1D
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;
}
83
jPO

オブジェクトのキーを取得し、配列の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);
32
Patrick Evans

lodash function _.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'] }
31
Ohad Sadan

ES6を使用:

const obj = { a: "aaa", b: "bbb", c: "ccc", d: "ddd" };
Object.assign({}, ...Object.entries(obj).map(([a,b]) => ({ [b]: a })))
29
grappeq

ES6/ES2015では、 Object.keysreduce の使用を新しい Object.assign 関数、 矢印関数 、および 計算されたプロパティ名 は、非常に単純な単一ステートメントのソリューションです。

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

オブジェクトスプレッド演算子 (これを書いている段階3)を使用してトランスパイルしている場合は、物事がさらに簡単になります。

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

最後に、 Object.entries を使用できる場合(執筆時点のステージ4)、ロジックを少しだけ(IMO)クリーンアップできます。

const foo = { a: 1, b: 2, c: 3 };
const bar = Object.entries(foo)
    .reduce((obj, [key, value]) => ({ ...obj, [value]: key }), {});
27
joslarson

これでObject.fromEntriesができました。

obj => Object.fromEntries(Object.entries(obj).map(a => a.reverse()))

または

obj => Object.fromEntries(Object.entries(obj).map(([k, v]) => ([v, k])))
5
Sc0ttyD

@joslarsonと@jPOの回答の補足として:
ES6なしで、 Object.keysArray.reduce を使用できますおよび カンマ演算子

Object.keys(foo).reduce((obj, key) => (obj[foo[key]] = key, obj), {});

Someい人もいるかもしれませんが、reduceが各ループのobjのすべてのプロパティを広げていないため、「ちょっと」速いです。

4
Vaidd4

Ramda を使用:

const swapKeysWithValues = 
  R.pipe(
    R.keys,
    R.reduce((obj, k) => R.assoc(source[k], k, obj), {})
  );

const result = swapKeysWithValues(source);
2
im.pankratov

試して

let swap = (o,r={})=> Object.keys(o).map(x=>r[o[x]]=x)&&r;
let obj = {A : 1, B : 2, C : 3, D : 4};

let swap = (o,r={})=> Object.keys(o).map(x=>r[o[x]]=x)&&r;

console.log(swap(obj));
2

純粋でポイントフリーのスタイルの純粋なラムダ:

const swapKeysAndValues = R.pipe(
   R.toPairs,
   R.map(R.reverse),
   R.fromPairs,
);

または、ES6のもう少し複雑なバージョンでも、純粋に機能します:

const swapKeysAndValues2 = obj => Object
    .entries(obj)
    .reduce((newObj, [key, value]) => ({...newObj, [value]: key}), {})
1
Pietro Bellone

invert-kvなどのnpmモジュールを使用して、このタスクを実行する方が良いと考えています。

invert-kv:オブジェクトのキー/値を反転します。例:{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'}
1
Huan
    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);
0
Anup Agarwal