2012-01-05 17 views
46

Necesito convertir un objeto a otro objeto js para pasar a un puesto de servidor en el que los nombres de las teclas se diferencian por ejemplo¿Hay alguna manera de cambiar el nombre de claves de objeto usando js underscore.js

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

necesidades de se convierten en

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

donde tengo obj de búsqueda disponible para el mapeo de todas las llaves

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

¿hay una func ion disponible en underscore.js o jQuery que puedo usar que tiene esta funcionalidad?

gracias

+3

No subrayado, pero tiene lodash [_.mapKeys] (https://lodash.com/docs#mapKeys) para modificar las teclas de un objeto. – CookieMonster

Respuesta

26

Por lo que sé, no hay ninguna función incorporada 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; 
}); 
1

No hay ninguna función en cualquier biblioteca que cambia el nombre explícitamente llaves. Su método también es el más rápido (consulte jsperf tests). 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.

+1

Los casos de prueba en el punto de referencia ni siquiera se ven iguales. – meandre

1

¿Por qué no utiliza 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> 
1

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

violín: http://jsfiddle.net/mr23/VdNjf/

+0

Aunque el ejemplo es artificial, en la vida real lo usé para construir un mapa de teclas de "limpieza" usando el primer registro de un conjunto de datos, y luego aplicarlo al resto (que puede incluir 'cargas' adicionales de datos). – mr23

+0

terminé usando la solución _.replace() anterior, pero comencé mirando su solución y plunkr. funciona bien. gracias – FireDragon

36

similares a @pimvdb, también puede hacerlo con un _.reduce:

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

violín: http://jsfiddle.net/T9Lnr/39/

+1

el violín ya no funciona – wegginho

+0

parece que todavía funciona para mí @wegginho, se imprime en la consola – dule

+0

Recibo un error que no se define subrayado – wegginho

34

Sé que no mencionó lodash y las respuestas ya resuelven el problema, pero como vine aquí en busca de una manera de hacerlo, pensé que alguien más podría aprovechar una alternativa.

Como @CookieMonster menciona en los comentarios, puede hacer esto con _.mapKeys:

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

y el violín: http://jsfiddle.net/cwkwtgr3/

+1

Los efectos secundarios son fuertes con este. – DFlores009

2

Se ha resuelto aquí https://stackoverflow.com/a/30940370/1360897

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

y también una mapeo de valores antiguos y nuevos, como este

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

Y a continuación, utilizando _.map y _.transform, puede 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; 
    }); 
}); 
10

Se puede copiar los valores de las propiedades nuevas con JavaScript estándar, y quitar las propiedades originales con omiten, de la siguiente manera:

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

Por favor, agregue algunas explicaciones. Actualmente, su respuesta está marcada como de "baja calidad" y podría ser eliminada. –

0

como user2387823 decía above usando omiten es una gran opción. Por ejemplo, podría escribir algo como esto

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(); 
} 

Esto puede ser más lenta que las respuestas anteriores.

Cuestiones relacionadas