Saltar al contenido

Renombrar/re-asignar eficientemente el objeto javascript/json keys dentro de array de objetos

Te damos la bienvenida a nuestro espacio, en este lugar vas a encontrar la respuesta que andabas buscando.

Solución:

Como ya mencioné en los comentarios, si puede hacer ciertas suposiciones sobre los valores de los objetos, podría usar una expresión regular para reemplazar el keyspor ejemplo:

str = str.replace(/"title":/g, '"name":');

No es tan “limpio”, pero podría hacer el trabajo más rápido.


Si tiene que analizar el JSON de todos modos, un enfoque más estructurado sería pasar un vivificador función a JSON.parse y es posible que pueda evitar un pase adicional sobre el array. Esto probablemente depende de cómo implemente el motor JSON.parse aunque (tal vez analizan todo string primero y luego haz una segunda pasada con la función reviver, en cuyo caso no obtendrías ninguna ventaja).

var arr = JSON.parse(str, function(prop, value) 
   switch(prop) 
     case "title":
        this.name = value;
        return;
     case "uid":
        this.id = value;
        return;
     default:
        return value;
   
);

Puntos de referencia, usando el script Node.js a continuación para probar 3 veces:

1389822740739: Beginning regex rename test
1389822740761: Regex rename complete
// 22ms, 22ms, 21ms
1389822740762: Beginning parse and remap in for loop test
1389822740831: For loop remap complete
// 69ms, 68ms, 68ms
1389822740831: Beginning reviver function test
1389822740893: Reviver function complete
// 62ms, 61ms, 60ms

Parece que la expresión regular (en este caso) es la más eficiente, pero tenga cuidado al intentar analizar JSON con expresiones regulares.


Script de prueba, cargando 100,230 líneas del JSON de muestra del OP:

fs = require('fs');
fs.readFile('test.json', 'utf8', function (err, data) 
    if (err) 
        return console.log(err);
    
    console.log(new Date().getTime() + ": Beginning regex rename test");
    var str = data.replace(/"title":/g, '"name":');
    str = str.replace(/"uid":/g, '"id":');
    JSON.parse(str);
    console.log(new Date().getTime() + ": Regex rename complete");
    console.log(new Date().getTime() + ": Beginning parse and remap in for loop test");
    var arr = JSON.parse(data);
    for (var i = 0; i < arr.length; i++) 
        arr[i].name = arr[i].title;
        arr[i].id = arr[i].uid;
        delete arr[i].title;
        delete arr[i].uid;
    
    console.log(new Date().getTime() + ": For loop remap complete");
    console.log(new Date().getTime() + ": Beginning reviver function test");
    var arr = JSON.parse(data, function (prop, value) 
        switch (prop) 
            case "title":
                this.name = value;
                return;
            case "uid":
                this.id = value;
                return;
            default:
                return value;
        
    );
    console.log(new Date().getTime() + ": Reviver function complete");
);

Hice esta pregunta hace mucho tiempo y, desde entonces, me he acostumbrado a usar Array.prototype.map() para hacer el trabajo, más por la estabilidad y la limpieza del código que por el rendimiento. Si bien ciertamente no es el más eficaz, se ve muy bien:

var repl = orig.map(function(obj) 
    return 
        name: obj.title,
        id: obj.uid
    
)

Si necesita una función más flexible (y compatible con ES6), intente:

let replaceKeyInObjectArray = (a, r) => a.map(o => 
    Object.keys(o).map((key) => ( key] : o[key] )
).reduce((a, b) => Object.assign(, a, b)))

p.ej

const arr = [ abc: 1, def: 40, xyz: 50 ,  abc: 1, def: 40, xyz: 50 ,  abc: 1, def: 40, xyz: 50 ]
const replaceMap =  "abc": "yyj" 

replaceKeyInObjectArray(arr, replaceMap)

/*
[
    
        "yyj": 1,
        "def": 40,
        "xyz": 50
    ,
    
        "yyj": 1,
        "def": 40,
        "xyz": 50
    ,
    
        "yyj": 1,
        "def": 40,
        "xyz": 50
    
]
*/

Aquí hay otra versión de la sugerencia del OP para usar map() para mayor claridad (no rendimiento).

var newItems = items.map(item => (
    name: item.title,
    id: item.uid
));

Esto utiliza funciones de flecha ES6 y las sintaxis de acceso directo que son posibles cuando solo se pasa un parámetro a la función y solo una declaración en el cuerpo de la función.

Dependiendo de su historial con expresiones lambda en varios idiomas, esta forma puede o no resonar con usted.

Tenga cuidado al devolver un objeto literal en la sintaxis de acceso directo de la función de flecha como esta. ¡No olvide los paréntesis adicionales alrededor del objeto literal!

Reseñas y calificaciones de la guía

Finalizando este artículo puedes encontrar los comentarios de otros sys admins, tú igualmente tienes la opción de dejar el tuyo si te apetece.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *