2014-04-11 15 views
31

Ho un oggetto JSON estremamente grande strutturata in questo modo:chiave swap con valore JSON

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

Ho bisogno di una funzione in grado di scambiare i valori con le chiavi nel mio oggetto e non so come farlo . Avrei bisogno di un output simile a questo:

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

C'è un modo che io possa fare questo avrebbe creato manualmente un nuovo oggetto in cui tutto è scambiato?
Grazie

+1

sono tutti valori numeri e si ripetono i numeri? Se i valori si ripetono, non sarai in grado di scambiarli perché sovrascriveranno gli altri, a meno che tu non modifichi il loro valore con un valore univoco. Potrebbe esserci una soluzione migliore per quale motivo è necessario lo swap? –

+0

@PatrickEvans Sono tutti numeri ma non si ripetono. Sto cercando di fare una cifra di base. – C1D

risposta

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

Esempio qui FIDDLE non dimenticate di accendere la console per vedere i risultati.

+0

Grazie mille per questo! Ho cercato tutto lo stackexchange e non sono riuscito a trovare una risposta. – C1D

+0

Siete i benvenuti :) – jPO

+1

la bellezza di questo è che funziona anche per 'javascript '.+ 1vote – AXL

21

Ottenere le chiavi dell'oggetto e quindi utilizzare la funzione di riduzione della matrice per scorrere ciascun tasto e impostare il valore come chiave e il tasto come valore.

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

è possibile utilizzare la funzione lodash _.invert può anche utilizzare 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

In ES6/ES2015 è possibile combinare l'uso di Object.keys e reduce con la nuova funzione Object.assign, un arrow function, e un computed property name per una soluzione a singola istruzione piuttosto semplice.

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

Se si sta utilizzando la transpiling object spread operator (fase 3 al momento di scrivere questo), che semplificherà le cose un po 'più.

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

Infine, se avete a disposizione Object.entries (fase 4 al momento di scrivere), è possibile pulire la logica di un tocco più (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: Token inaspettato (53:45) 51 | if (btoa) { 52 | entries = Object.entries (voci) > 53 | .reduce ((obj, [chiave, valore]) => ({... obj, [valore]: tasto}), {}); |^ – Superlokkus

+0

@Superlokkus la mia migliore interpretazione di quell'output di errore è che non si sta eseguendo la trascrizione della sintassi di diffusione degli oggetti e, ad oggi, non conosco alcun motore JavaScript che la supporti in modo nativo. – joslarson

3

Utilizzando ES6:

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

Utilizzando Ramda:

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

Come complemento di @joslarson e risposte @jPO:
Senza ES6 necessario, è possibile utilizzare Object.keysArray.reduce e il Comma Operator:

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

Alcuni potrebbero trovarlo brutto, ma è "kinda" più veloce poiché lo reduce non distribuisce tutte le proprietà dello obj su ciascun ciclo.

Problemi correlati