Create a dynamic object recursively

Asked

Viewed 246 times

0

I’m getting my ass kicked to make a very simple stop: assemble an object in Javascript by an array (exploded string).

I need to mount an object dynamically (recursive) like this:

{
  caneta: { cor: { hexadecimal: null } }
}

just with that array: ['cor', 'caneta', 'hexadecimal']

I need to do this recursively, because my array can have 1 property, or 800.


Context

I have a function that reads all forms on my page and assembles, according to the name of each input, an object, and, according to the form id, stores everything within a parent object (date).

Example:

that:

<form id="batata">
  <input name="tomate">
  <input name="banana" value="123">
</form>

generates an object like this:

batata: {
  tomate: null,
  banana: '123',
};

Failed attempt and complete context in Gist

  • 1

    I don’t understand why you want something recursive. And the order/hierarchy of the properties in the object is different even from the array order, as in your example?

  • She needs to call herself to get the same treatment in all cases, doesn’t she? And yes, it will be forward.

  • 1

    So the object is pen/color/Hex and the array is color/pen/Hex? Is that right? Is there a reason why it’s not in the same order? Criteria?

2 answers

1

I’ve devised an alternative using object functions Array javascript that I particularly like enough:

var obj = ['cor', 'caneta', 'hexadecimal'] 
.concat([null]) //Remover caso não queira que o ultimo seja sempre null
.reverse()
.reduce(function(a,b){
 return {[b]:a}
});
console.log(obj)

References:

Array Reduce - The reduce() method performs a Reducer function (provided by you) for each member of the array, resulting in a single return value.

Array Concat - The Concat() method returns a new array containing all arrays or values passed as parameter

Array Reverse - The Reverse() method inverts the items of an array. The first element of the array becomes the last and the last becomes the first.

  • Good idea. I have only questions about support for this syntax {[b]:a}, in older JS engines should not work.

  • Yes, in this case just create an empty object and add the value at the position: var x = {}; x[b]= a; return x

1

If I understand the question correctly, and if it is to follow the order of the properties as it is in the array (in your example there is an inversion), nothing recursive is needed, just a loop.

See the example below, with line-by-line explanations in the form of comments:

// Lista de propriedades, considerando que uma
// é filha da outra.
var arr = ['caneta', 'cor', 'hexadecimal'];

// Guarda temporariamente cada item da array
let prop;

// Estado inicial do objeto é vazio
let obj = {};

// Referencia adicional ao objeto.
// Será modificada dentro do loop.
let path = obj;

// Loop tratando os elementos da array,
// um a um, na ordem.
while (prop = arr.shift()) {
  // Cria a propriedade atual
  // (com valor null no último nível)
  path[prop] = arr.length ? {} : null;
  
  // Path agora será o valor da propriedade
  // que acabamos de inserir.
  path = path[prop];
}

// Imprime o resultado
console.log(obj);

NOTE: This code changes the original array, which is empty at the end of the loop. If you don’t want this side effect, adapt to a for(;;) normal without the use of shift, is simple.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.