2014-04-11 16 views
31

Mam bardzo duży obiekt JSON zorganizowany tak:klucz SWAP z wartości JSON

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

Potrzebuję funkcji, które mogą wymieniać wartości z kluczami w moim obiektu i nie wiem jak to zrobić . Potrzebuję takiego wyjścia:

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

Czy jest jakiś sposób, aby to zrobić ręcznie ręcznie nowy obiekt, w którym wszystko jest zamienione?
Dzięki

+1

są numerami wartości i czy liczby się powtarzają? Jeśli wartości powtarzają się, nie będziesz mógł ich zamieniać, ponieważ nadpiszeją inne, chyba że zmienisz ich wartość na jakąś unikalną wartość. Być może istnieje lepsze rozwiązanie, z jakiego powodu wymagana jest zamiana? –

+0

@PatrickEvans Wszystkie są liczbami, ale się nie powtarzają. Próbuję stworzyć podstawowy szyfr. – C1D

Odpowiedz

45
function swap(json){ 
    var ret = {}; 
    for(var key in json){ 
    ret[json[key]] = key; 
    } 
    return ret; 
} 

Przykład tutaj FIDDLE Nie zapomnij włączyć konsoli, aby zobaczyć wyniki.

+0

Dziękuję bardzo za to! Przeszukałem cały stackexchange i nie mogłem znaleźć odpowiedzi. – C1D

+0

Serdecznie zapraszamy :) – jPO

+1

Piękno tego, co działa również dla 'javascript'.+ 1-na-maszynowa – AXL

21

Uzyskaj klucze obiektu, a następnie za pomocą funkcji redukcji macierzy przejdź przez każdy klucz i ustaw wartość jako klucz, a klucz jako wartość.

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); 
15

można użyć lodash funkcję _.invert również mogą korzystać 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'] } 
11

W ES6/ES2015 można połączyć stosowanie Object.keys i reduce z nowym Object.assign funkcji, jak arrow function oraz computed property name dla dość prostego rozwiązania pojedynczej instrukcji.

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

Jeśli transpiling pomocą object spread operator (etap 3 w momencie pisania tego), który będzie uprościć nieco dalej.

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

Wreszcie, jeśli masz Object.entries dostępne (etap 4 jako pisania), można oczyścić logikę trochę bardziej (IMO).

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

SyntaxError: /Users/markus/Entwicklung/IT1_Beleg/public/es6/vokabeltrainer.js: Nieoczekiwany token (53:45) 51 | jeśli (btoa) { 52 | wpisy = Object.entries (wpisy) > 53 | .reduce ((obj, [key, value]) => ({... obj, [value]: key}), {}); |^ – Superlokkus

+0

@Superlokkus Moja najlepsza interpretacja tego wyjścia błędu polega na tym, że nie transponujesz składni rozproszonej obiektu, a na dzień dzisiejszy nie znam żadnych silników JavaScript, które ją obsługują natywnie. – joslarson

3

Korzystanie ES6:

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

Korzystanie Ramda:

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

Jako uzupełnienie @joslarson i odpowiedzi @jPO:
Bez ES6 potrzebne, można użyć Object.keysArray.reduce i Comma Operator:

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

Niektóre mogą być brzydkie, ale są "trochę" szybsze, ponieważ reduce nie rozprzestrzenia wszystkich właściwości obj w każdej pętli.