Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

131
Visualizações
Is it possible to update specific value of nested object with lodash?

I have a nested object like this

let obj = {
  id: "XXX",
  children: [
    {
      id: "YYY",
      children: [],
      path: ["XXX", "YYY"],
      type: "text"
    },
    {
      id: "ZZZ",
      children: [],
      path: ["XXX", "ZZZ"],
      type: "button"
    }
  ],
  path: ["XXX"],
  type: "row"
};

I need to loop through all the children and update the path by appending an array of strings which is is const newPath = ["A", "B", "C"];

let newObj = cloneDeepWith(obj, (node) => {
  if (node.id) {
    node = { ...node, path: [...newPath, ...node.path] };
    console.log("updated : ", node)
  }
});

So final output of update object should be this

let obj = {
  id: "XXX",
  children: [
    {
      id: "YYY",
      children: [],
      path: ["A", "B", "C", "XXX", "YYY"],
      type: "text"
    },
    {
      id: "ZZZ",
      children: [],
      path: ["A", "B", "C", "XXX", "ZZZ"],
      type: "button"
    }
  ],
  path: ["A", "B", "C", "XXX"],
  type: "row"
};

I'm trying to do it with cloneDeepWith function in lodash like this

let updatedObj = cloneDeepWith(obj, (node) => {
  if (node.id) {
    node = { ...node, path: [...newPath, ...node.path] };
    console.log("updated : ", node)
  }
});

In every console.log it prints the corrected updated node (in this case 3 with parent node) , but it doesn't return in updatedObj

How can I achieve this ?

about 4 years ago · Santiago Gelvez
3 Respostas
Responde à pergunta

0

I'm not sure how to do this is lodash, but doing in plain JS is pretty easy. Your recursion tag is the key..

eg.

let obj = {
  id: "XXX",
  children: [
    {
      id: "YYY",
      children: [],
      path: ["XXX", "YYY"],
      type: "text"
    },
    {
      id: "ZZZ",
      children: [],
      path: ["XXX", "ZZZ"],
      type: "button"
    }
  ],
  path: ["XXX"],
  type: "row"
};

function addABC(obj) {
  if (obj.path) obj.path = ['A','B','C',...obj.path];
  if (obj.children) for (const s of obj.children) addABC(s);
}

addABC(obj);

console.log(obj);

about 4 years ago · Santiago Gelvez Relatório

0

You could do this with Lodash using cloneDeepWith method but in this case it will also modify original data.

let obj = {
  id: "XXX",
  children: [{
      id: "YYY",
      children: [],
      path: ["XXX", "YYY"],
      type: "text"
    },
    {
      id: "ZZZ",
      children: [],
      path: ["XXX", "ZZZ"],
      type: "button"
    }
  ],
  path: ["XXX"],
  type: "row"
};

const newPath = ["A", "B", "C"];

const clone = _.cloneDeepWith(obj, value => {
  if (_.isArray(value.path)) {
    value.path = [...newPath, ...value.path]
  }
})

console.log(clone)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

about 4 years ago · Santiago Gelvez Relatório

0

An immutable approach without a library could look like this:

const prependPaths = (prefix) => ({path, children, ...rest}) => ({
  ...rest,
  path: [...prefix, ...path],
  children: children .map (prependPaths (prefix))
})

const obj = {id: "XXX", children: [{id: "YYY", children: [], path: ["XXX", "YYY"], type: "text"}, {id: "ZZZ", children: [], path: ["XXX", "ZZZ"], type: "button"}], path: ["XXX"], type: "row"}

console .log (prependPaths (['A', 'B', 'C']) (obj))
.as-console-wrapper {max-height: 100% !important; top: 0}

This is a straightforward recursion, where we map over the children using our function, preconfigured with the prefix parameter (here, ['A', 'B', 'C'].)

But notice that your objects' path nodes carry some redundant information that could be derived from the hierarchy of ids, and if you have a raw form that doesn't include these path nodes, you could still achieve the same effect with about the same effort:

const addPaths = (prefix = []) => ({id, children, ...rest}) => ({
  id,
  ...rest,
  path: [...prefix, id],
  children: children .map (addPaths ([...prefix, id]))
})

// No `path` nodes here.
const obj2 = {id: "XXX", children: [{id: "YYY", children: [], type: "text"}, {id: "ZZZ", children: [], type: "button"}], type: "row"}

// But the output includes the correct full paths.
console .log (addPaths (['A', 'B', 'C']) (obj2))
.as-console-wrapper {max-height: 100% !important; top: 0}

The chief difference is that the recursive calls take an updated version of the prefix, adding the id of the current object.

about 4 years ago · Santiago Gelvez Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda