Eu tenho um conjunto de dados contendo o nome da variável sublinhado (_). Como abaixo:
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'
}
Eu quero dividi-los em objeto aninhado / matriz, abaixo está o resultado que eu quero.
{
m: {
name: "my name",
address: "my address"
},
p: {
"1": {category: 'cat 1', name: 'name 1'},
"2": {category: 'cat 2', name: 'name 2'}
}
}
Como posso escrever um método recursivo para obtê-lo em vez de codificado? Talvez deva permitir manipular objetos aninhados mais profundos, como "p_2_one_two_category: 'value'" em 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);
javascript
arrays
object
recursion
Devb
fonte
fonte
m
é um objeto simples, não uma matriz de objetos de propriedade única.) Esses resultados parecem muito mais lógicos que a saída de amostra. É isso que você realmente quer?Respostas:
Você pode usar o
reduce
método que criará uma estrutura aninhada semelhante com apenas objetos.fonte
Não sei se esse formato de saída era o que você realmente estava procurando ou simplesmente o melhor que conseguiu. Uma alternativa seria gerar algo parecido com isto:
Há uma grande diferença entre isso e a saída do seu código.
p
agora é uma matriz simples de objetos, em vez de um objeto1
- e -2
indexado. É bem possível que isso não seja útil para você, mas é uma alternativa interessante. Há também uma segunda diferença em relação à saída de amostra que você forneceu. O código original e a resposta do Nenad retornam emm: {name: "my name", address: "my address"}
vez do solicitadom: [{name: "my name"}, {address: "my address"}]
. Isso parece muito mais lógico para mim, e eu também fiz dessa maneira.Aqui está um código que faria isso:
Este código é inspirado no Ramda (do qual sou autor). O utilitário funciona
path
,assoc
eassocPath
possui APIs semelhantes às do Ramda, mas essas são implementações exclusivas (emprestadas de outra resposta .) Como essas são incorporadas ao Ramda, somente ahydrate
função seria necessária se o seu projeto usasse o Ramda.A grande diferença entre essa e a resposta de Nenad (excelente!) É que a hidratação de nosso objeto leva em consideração a diferença entre as chaves de string, que são consideradas objetos simples, e as numéricas, que são consideradas matrizes. No entanto, como eles são divididos em nossa string inicial (
p_1_category
), isso pode levar à ambiguidade, se às vezes você desejar que esses sejam objetos.Também uso um truque que é um pouco feio e talvez não seja dimensionado para outros valores numéricos: subtraio 1 do número para que o
1
in sejap_1_category
mapeado para o índice zeroth. Se seus dados de entrada parecessem, emp_0_category ... p_1_category
vez dep_1_category ... p_2_category
podermos pular isso.Em qualquer caso, há uma chance real de que isso seja contrário aos seus requisitos subjacentes, mas pode ser útil para outras pessoas.
fonte
path
poderia ser ops.reduce((o = {}, p) => o[p], obj)
que é justops.reduce(prop, obj)
?path
possa funcionar nesse caso específico, ela perde a segurança nula da versão acima. Concordou com a variedade de respostas; parece que perguntas interessantes podem trazer muitas alternativas interessantes.nenhuma classificação necessária
A saída proposta em sua postagem não segue um padrão. Alguns itens agrupam em matrizes, enquanto outros agrupam em objetos. Como objetos semelhantes a matrizes se comportam como matrizes , apenas usaremos objetos.
A saída nesta resposta é a mesma que a de Nenad, mas este programa não exige que as chaves do objeto sejam classificadas previamente -
Resultado -
fundir
Estou emprestando um genérico
merge
que escrevi em outra resposta. As vantagens de reutilizar funções genéricas são numerosas e não as reiterarei aqui. Leia a postagem original se quiser saber mais -Mesclagem superficial funciona como esperado -
E fundas profundas também -
Expanda o snippet abaixo para ver nosso resultado em seu próprio navegador -
Mostrar snippet de código
fonte
Use o
forEach
loop no objeto.Dividir a chave com base no separador e percorrer a matriz
Até a última chave, crie um objeto vazio e mantenha o objeto atual no ponteiro / corredor.
Na última chave, basta adicionar o valor.
fonte