javascript - ¿Hay alguna manera de cambiar el nombre de las claves del objeto js utilizando underscore.js
jquery (10)
Necesito convertir un objeto js a otro objeto para pasar a una publicación del servidor donde los nombres de las claves difieren por ejemplo
var a = {
name : "Foo",
amount: 55,
reported : false,
...
<snip/>
...
date : "10/01/2001"
}
tiene que convertirse en
a = {
id : "Foo",
total : 55,
updated: false,
...
<snip/>
...
issued : "10/01/2001"
}
donde tengo obj de búsqueda disponible para mapear todas las claves
var serverKeyMap = {
name : "id",
amount : "total",
reported : "updated",
...
date : "issue"
}
¿Hay alguna función disponible en underscore.js o jQuery que pueda usar que tenga esta funcionalidad?
Gracias
¿Por qué no usas este simple script java? Valor de cualquier clave: el par de valores debe ser string / number / Boolean.
<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>
Como dijo user2387823 above 👆, omitir es una gran opción. Por ejemplo, podrías escribir algo como esto
function updateObjKey(obj, currentKey, newKey) {
var keyValue = obj[currentKey];
obj = _.omit(obj, [currentKey]);
obj[newKey] = keyValue;
return obj;
}
Hasta donde sé, no hay ninguna función integrada en ninguna de estas dos bibliotecas. Sin embargo, puedes crear el tuyo con bastante facilidad: http://jsfiddle.net/T9Lnr/1/ .
var b = {};
_.each(a, function(value, key) {
key = map[key] || key;
b[key] = value;
});
No, no hay ninguna función en ninguna biblioteca que cambie el nombre de las claves explícitamente. Su método también es el más rápido (consulte las pruebas jsperf ). Su mejor opción , si es posible, es refactorizar el código del lado del cliente o del servidor para que los objetos sean los mismos.
Puede copiar los valores a las nuevas propiedades con JavaScript estándar y eliminar las propiedades originales con omitir , de la siguiente manera:
a.id = a.name;
a.total = a.amount;
a.updated = a.reported;
a = _.omit(a, ''name'', ''amount'', ''reported'');
Sé que no mencionó lodash y las respuestas ya resuelven el problema, pero alguien más podría aprovechar una alternativa.
Como @CookieMonster mencionado en los comentarios, puedes hacer esto con _.mapKeys
:
_.mapKeys(a, function(value, key) {
return serverKeyMap[key];
});
Y el violín: http://jsfiddle.net/cwkwtgr3/
Se ha resuelto aquí https://.com/a/30940370/1360897
var keyMapping = {''PropertyA'': ''propertyA'', ..., ''PropertyF'': ''propertyNEW''}
y también un mapeo de valores antiguos y nuevos, como este
var valueMapping = {''Y'': true, ''F'': false}
Y luego usando _.map y _.transform, puedes transformar el objeto, como este
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;
});
});
Similar a @pimvdb, también puedes hacerlo con _.reduce
:
_.reduce(a, function(result, value, key) {
key = map[key] || key;
result[key] = value;
return result;
}, {});
Fiddle: http://jsfiddle.net/T9Lnr/39/
Tengo un operador de transformación y me gustaría aplicarlo a todas las claves. Bifurqué el violín de pimvdb para producir un ejemplo simple. En este caso, capitaliza la clave. Y construye dinámicamente el mapa de teclas, que necesitaba para asegurar mi trabajo (gracias JSFiddle).
Aquí está el código cambiado:
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/
// 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();
}
Esto puede ser más lento que las respuestas anteriores.