Tengo un conjunto de datos que contiene el nombre de la variable de subrayado (_). Como a continuación:
const data = {
m_name: 'my name',
m_address: 'my address',
p_1_category: 'cat 1',
p_1_name: 'name 1',
p_2_category: 'cat 2',
p_2_name: 'name 2'
}
Quiero dividirlos en un objeto / matriz anidado, a continuación se muestra el resultado que quiero.
{
m: {
name: "my name",
address: "my address"
},
p: {
"1": {category: 'cat 1', name: 'name 1'},
"2": {category: 'cat 2', name: 'name 2'}
}
}
¿Cómo puedo escribir un método recursivo para lograrlo en lugar de codificarlo? Tal vez debería permitir manejar objetos anidados más profundos como "p_2_one_two_category: 'value'" en p: {2: {one: {two: category: 'value'}}}
var data ={
m_name: 'my name',
m_address: 'my address',
p_1_category: 'cat 1',
p_1_name: 'name 1',
p_2_category: 'cat 2',
p_2_name: 'name 2',
p_2_contact: '1234567',
k_id: 111,
k_name: 'abc'
}
var o ={};
Object.keys(data).forEach(key => {
var splited = key.split(/_(.+)/);
if (!o[splited[0]]) {
o[splited[0]] = {};
}
var splited1 = splited[1].split(/_(.+)/);
if (splited1.length < 3) {
o[splited[0]][splited[1]] = data[key];
} else {
if (!o[splited[0]][splited1[0]]){
o[splited[0]][splited1[0]] = {};
}
o[splited[0]][splited1[0]][splited1[1]] = data[key];
}
});
console.log(o);
m
es un objeto simple, no una matriz de objetos de propiedad única). Estos resultados parecen mucho más lógicos que su salida de muestra. ¿Es eso lo que realmente quieres?Respuestas:
Podría usar un
reduce
método que creará una estructura anidada similar con solo objetos.fuente
No sé si ese formato de salida era lo que realmente estaba buscando o simplemente lo mejor que pudo lograr. Una alternativa sería generar algo como esto:
Hay una gran diferencia entre esto y la salida de su código.
p
es ahora un array plano de objetos en lugar de un1
- y2
objeto -indexed. Es muy posible que esto no sea útil para usted, pero es una alternativa interesante. También hay una segunda diferencia con respecto a la salida de muestra que proporcionó. Tanto su código original como la respuesta de Nenad devuelven enm: {name: "my name", address: "my address"}
lugar de la solicitadam: [{name: "my name"}, {address: "my address"}]
. Esto me parece mucho más lógico, y también lo he hecho de esta manera.Aquí hay un código que haría esto:
Este código está inspirado en Ramda (del cual soy autor). Las funciones de utilidad
path
,assoc
yassocPath
tienen APIs similares a Ramda de, pero estos son implementaciones únicas (tomados de otra respuesta .) Puesto que éstos se construyen en Ramda, sólo elhydrate
sería necesario función de si su proyecto utiliza Ramda.La gran diferencia entre esto y la respuesta de Nenad (¡excelente!) Es que nuestra hidratación de objetos tiene en cuenta la diferencia entre las teclas de cadena, que se supone que son para objetos simples, y las numéricas, que se supone que son para matrices. Sin embargo, dado que estos están separados de nuestra cadena inicial (
p_1_category
), esto podría generar ambigüedad si a veces desea que sean objetos.También utilizo un truco que es un poco feo y que tal vez no se escalará a otros valores numéricos: resto 1 del número para que el
1
in sep_1_category
asigne al índice cero. Si los datos de entrada parecía quep_0_category ... p_1_category
en lugar dep_1_category ... p_2_category
que podría saltar este.En cualquier caso, existe una posibilidad real de que esto sea contrario a sus requisitos subyacentes, pero podría ser útil para otros.
fuente
path
podría ser lops.reduce((o = {}, p) => o[p], obj)
que es justops.reduce(prop, obj)
?path
podría funcionar para este caso específico, pierde la seguridad nula de la versión anterior. De acuerdo sobre la variedad de respuestas; Parece que las preguntas interesantes pueden traer muchas alternativas interesantes.no se requiere clasificación
El resultado propuesto en su publicación no sigue un patrón. Algunos elementos se agrupan en matrices, mientras que otros se agrupan en objetos. Dado que los objetos tipo matriz se comportan como matrices , solo utilizaremos objetos.
El resultado en esta respuesta es el mismo que el de Nenad, pero este programa no requiere que las claves del objeto estén ordenadas de antemano:
Salida -
unir
Estoy tomando prestado un genérico
merge
que escribí en otra respuesta. Las ventajas de reutilizar funciones genéricas son numerosas y no las reiteraré aquí. Lea la publicación original si desea saber más:Shallow combina el trabajo como se esperaba
Y las fusiones profundas también ...
Expanda el fragmento a continuación para ver nuestro resultado en su propio navegador:
Mostrar fragmento de código
fuente
Usa el
forEach
bucle en el objeto.Divida la clave según el separador y recorra la matriz
Hasta la última clave, cree un objeto vacío y mantenga el objeto actual en puntero / corredor.
En la última clave, simplemente agregue el valor.
fuente