2012-01-05 7 views
46

Ho bisogno di convertire un oggetto js ad un altro oggetto per il passaggio su un post server in cui i nomi delle chiavi differiscono per esempioEsiste un modo per rinominare chiavi oggetto js utilizzando underscore.js

var a = { 
    name : "Foo", 
    amount: 55, 
    reported : false, 
    ... 
    <snip/> 
    ... 
    date : "10/01/2001" 
    } 

esigenze di trasformarsi in

a = { 
    id : "Foo", 
    total : 55, 
    updated: false, 
    ... 
    <snip/> 
    ... 
    issued : "10/01/2001" 
    } 

dove ho ricerca obj disponibili per la mappatura di tutte le chiavi

var serverKeyMap = { 
    name : "id", 
    amount : "total", 
    reported : "updated", 
    ... 
    date : "issue" 
    } 

c'è un funct ion disponibile in underscore.js o jQuery che posso usare che fa questa funzionalità?

grazie

+3

Non sottolineato, ma lodash ha [_.mapKeys] (https://lodash.com/docs#mapKeys) per la modifica delle chiavi di un oggetto. – CookieMonster

risposta

26

Per quanto ne so, non vi è alcuna funzione incorporata in nessuna di queste due librerie. Puoi creare il tuo abbastanza facilmente, però: http://jsfiddle.net/T9Lnr/1/.

var b = {}; 

_.each(a, function(value, key) { 
    key = map[key] || key; 
    b[key] = value; 
}); 
1

No, non c'è alcuna funzione in entrambi libreria che rinomina in modo esplicito le chiavi. Il tuo metodo è anche il più veloce (vedi jsperf tests.) La soluzione migliore, se possibile, è quella di rifattorizzare il lato client o il codice lato server in modo che gli oggetti siano gli stessi.

+1

I test case nel benchmark non sono nemmeno uguali. – meandre

1

Perché non usi questo semplice script java? Valore di qualsiasi chiave: coppia di valori dovrebbe essere stringa/numero/Booleano.

<script type="text/javascript">  
    var serverKeyMap = { 
     name : "id", 
     amount : "total", 
     reported : "updated" 
    }; 

    var a = { 
     name : "Foo", 
     amount: 55, 
     reported : false 
    }; 

    var b={}; // b is object where you will get your output 

    for(i in serverKeyMap) b[serverKeyMap[i]]=a[i]; 

    console.log(b); // It gives what you need. 

</script> 
1

Ho un operatore di trasformazione e vorrei solo applicarlo a tutte le chiavi. Ho biforcato il violino di pimvdb per produrre un semplice esempio. In questo caso, Capitalizza la chiave. E crea dinamicamente la mappa dei tasti, di cui avevo bisogno per assicurare i lavori (grazie a JSFiddle).

Ecco il codice modificato:

var keymap = {}; 
_.each(a, function(value, key) { 
    var oldkey = key; 
    key = capitalize(key); 
    keymap[oldkey] = key; 
}); 
_.each(a, function(value, key) { 
    key = keymap[key] || key; 
    b[key] = value; 
}); 

Fiddle: http://jsfiddle.net/mr23/VdNjf/

+0

Anche se l'esempio è inventato, nella vita reale l'ho usato per creare una keymap di 'pulizia' utilizzando il primo record di un set di dati, e quindi applicarlo al resto (che potrebbe includere ulteriori 'carichi' di dati). – mr23

+0

ho finito per utilizzare la soluzione _.replace() sopra, ma ho iniziato osservando la soluzione e plunkr. funziona bene. grazie – FireDragon

36

Simile a @pimvdb, si può anche fare con un _.reduce:

_.reduce(a, function(result, value, key) { 
    key = map[key] || key; 
    result[key] = value; 
    return result; 
}, {}); 

Fiddle: http://jsfiddle.net/T9Lnr/39/

+1

il violino non funziona più – wegginho

+0

sembra funzionare ancora per me @wegginho, stampa sulla console – dule

+0

Ricevo un errore che sottolineatura non è definito – wegginho

34

So che non hai menzionato lo lodash e le risposte risolvono già il problema, ma mentre venivo qui cercando un modo per farlo, pensavo che qualcun altro potesse approfittare di un'alternativa.

Come @CookieMonster accennato nei commenti, si può fare questo con _.mapKeys:

_.mapKeys(a, function(value, key) { 
    return serverKeyMap[key]; 
}); 

e il violino: http://jsfiddle.net/cwkwtgr3/

+1

Gli effetti collaterali sono forti con questo. – DFlores009

2

E 'stato risolto qui https://stackoverflow.com/a/30940370/1360897

var keyMapping = {'PropertyA': 'propertyA', ..., 'PropertyF': 'propertyNEW'} 

e anche un mappatura di valori vecchi e nuovi, come questo

var valueMapping = {'Y': true, 'F': false} 

e quindi utilizzando _.map e _.transform, è possibile trasformare l'oggetto, come questo

var result = _.map(allItems, function(currentObject) { 
    return _.transform(currentObject, function(result, value, key) { 
     if (key === 'PropertyF' || key === 'PropertyG') { 
      value = valueMapping(value); 
     } 
     result[keyMapping[key]] = value; 
    }); 
}); 
10

Si potrebbe copiare i valori per le nuove proprietà con standard di JavaScript, e rimuovere le proprietà originali con omettere, come segue:

a.id = a.name; 
a.total = a.amount; 
a.updated = a.reported; 
a = _.omit(a, 'name', 'amount', 'reported'); 
+0

Per favore aggiungi qualche spiegazione. Attualmente la tua risposta è contrassegnata come "di bassa qualità" e potrebbe essere rimossa. –

0

come user2387823 stava dicendo above utilizzando omettere è una grande opzione. Per esempio si potrebbe scrivere qualcosa di simile

function updateObjKey(obj, currentKey, newKey) { 
    var keyValue = obj[currentKey]; 
    obj = _.omit(obj, [currentKey]); 
    obj[newKey] = keyValue; 
    return obj; 
    } 
1
// key_map: {old_name1: new_name1, ... } 
function rename_keys(object, key_map, is_picked=false){ 
    keys = _.keys(key_map); 
    new_keys = _.values(key_map); 
    picked = _.pick(object, keys); 
    renamed = _.object(new_keys, _.values(picked)); 
    if(is_picked) return renamed; 

    return _.chain(object).omit(keys).extend(renamed).value(); 
} 

Questo può essere più lento di risposte di cui sopra.