banner



How To Create A Set In Javascript

How to create nested child objects in Javascript from array?

list = [a,b,c] array to below object form using javascript

                                  a:{                  b                  : {         c : {         }     } }                              

Start a personal dev blog on your domain for free and grow your readership.

3.4K+ developers have started their personal blogs on Hashnode in the last one month.

Write in Markdown · Publish articles on custom domain · Gain readership on day zero · Automatic GitHub backup and more

Sai Kishore Komanduri's photo

Edit

On a second thought, makeNestedObjWithArrayItemsAsKeys can further be simplified, and written concisely!

                    const makeNestedObjWithArrayItemsAsKeys =                                              (arr)                        =>                      {   const reducer =                                              (acc, item)                        =>                      ({ [item]: acc });                      return                      arr.reduceRight(reducer, {}); };                                      

cc: dvv.avinash Ivan Rahul Sidhant Siddarthan

The Object.assign in the original function (below) is unnecessary... have noticed it thanks to Jason's answer!

It'd be amiss on my part, to not mention that Jason's solution here (as I see it) is the most elegant one of the lot!


                    const makeNestedObjWithArrayItemsAsKeys =                                              (arr)                        =>                      {                      return                      arr.reduceRight(                                              (accumulator, item)                        =>                      {       const newAccumulator = {};       newAccumulator[item] = Object.assign(         {},         accumulator       );                      return                      newAccumulator;     },     {}   ); };                                      

Given the following list:

                                          const                      list                      = ["a",                      "b",                      "c"];                                      

...the return value of makeNestedObjWithArrayItemsAsKeys(list) will be the following object:

                    {                      a: {     b: {       c: {}     }   } }                                      

Hope that answers your question! :)

Sidhant Panda's photo

+2 Beers for that function name! 🙌

Jason Knight's photo

Whilst it's fun to see all the complex answers, mine's a bit more draconian... you probably won't find a faster routine for doing this. It exploits that objects are always passed by reference in JavaScript, even during assignment.

                                                                  function                        nest(arr)                      {                      for                      (var                      obj = {}, ptr = obj, i =                      0, j = arr.length; i < j; i++)         ptr = (ptr[arr[i]] = {});                      return                      obj; }                                      

No recursive calls, no fancy mapping/each, no nested function calls/multiple functions, no long-winded objectAssign, no foreach or other methods that won't work in legacy browsers. Just a simple FOR loop and assignment. Should work all the way back to IE5.

Show + 2 replies

Jason Knight's photo

Sai Kishore Komanduri Even better, if you don't care about IE8/earlier, you can lose the () from that reducing it to just:

ptr = ptr[arr[i]] = {};

I only included the extra () to be sure it works all the way back to IE 5.x since I'm obnoxious that way.

Dave Stewart's photo

since I'm obnoxious that way.

... plus that's your favourite browser :P

Ivan Bacher's photo

                    let                      list                      = ['a',                      'b',                      'c']  let root = {} let                      parent                      =                      null;                      for(let el of                      list) {                      if(parent                      ===                      null)                      parent                      = nest(el, root)                      else                      {                      parent                      = nest(el,                      parent);     } }                                              function                        nest                        (el, parent)                      {     let node = {}                      parent[el] = node;                      return                      node; }  console.log(root);                                      

Output

                    {                      a: { b: { c: {} } } }                                      

Show + 1 replies

Ivan Bacher's photo

The function nest() takes two parameters 1) el and 2) parent.

The first time nest is called we pass a (first element of the array) and root to the function.

Nest() creates a new object called node. Node then gets added to the parent parameter. Parent corresponds to root the first time the function is called. Then node is returned.

A reference of node is actually returned and not a copy (THIS IS IMPORTANT). Therefore, when nest() gets called a second time the parent parameter is actually a reference to the first node object that was created in the previously called nest() function.

Vidhyasimhan J's photo

Hi Ivan,

Your approach looks working. I have a doubt.

I wanted the output to be: { a: { b: { c: [{d:e,f:h} } } }

I modified the function nest where if el is equal to c, then add [] instead of {}. After that I cannot achieve adding key,value pairs inside the array [].

If I use root to add KVP, its adding like "{c:[],{d:e,...}} (where I need the d,e inside the array)

Can you guide me here?

Dave Stewart's photo

IMHO this question is too abstract to be of any transferrable value - you haven't said why you want to do this, though I suspect your example is simply too generic.

I'm not saying there isn't any value in such a reduction algorithm; it's just meaningless without context – anyone who answers has no guarantee they'll be providing something of practical use.

  • Where is the data coming from?
  • What value should be in the final nested result?
  • Will the structure already exist?
  • Can it take an input value?
  • Will it done by machines or humans?
  • Etc...

If all these are requirements, I suggest looking at Lodash set() :

  • https://lodash.com/docs/4.17.4#set

Sets the value at path of object. If a portion of path doesn't exist, it's created. Arrays are created for missing index properties while objects are created for all other missing properties. Use _.setWith to customize path creation.

As a programming exercise, my take on it is:

                    function                      set(keys,                      value, obj) {     obj = obj || {}                      keys                      = typeof                      keys                      ===                      'string'                      ?                      keys.match(/\w+/g)         :                      Array.prototype.slice.apply(keys)                      keys.reduce(function(obj,                      key,                      index) {         obj[key] =                      index                      ===                      keys.length                      -                      1                      ?                      value                      : typeof obj[key] ===                      'object'                      && obj !==                      null                      ? obj[key]                 : {}                      return                      obj[key]     }, obj)                      return                      obj }  //                      new                      object                      var                      obj =                      set(['a',                      'b',                      'c'],                      1) //  { a: { b: {                      c:                      1                      } } }   // existing objects                      set(['b',                      'c'],                      2, obj) // { a: { b: {                      c:                      1                      } }, b: {                      c:                      2                      } }   //                      new                      props                      set(['x',                      'y'],                      3, obj.b) // { a: { b: {                      c:                      1                      } }, b: {                      c:                      2, x: { y:                      3                      } } }   // existing props                      set(['x',                      'z'],                      4, obj.b) // { a: { b: {                      c:                      1                      } }, b: {                      c:                      2, x: { y:                      3, z:                      4                      } } }   //                      keys                      as                      string                      set('x y z',                      5, obj) // { a: { b: {                      c:                      1                      } }, b: {                      c:                      2, x: { y:                      3, z:                      4                      } }, x: { y: { z:                      5                      } } }  obj                                      

In general programming terms, usability and practicality is more valuable than brevity or speed.

Show + 1 replies

Dave Stewart's photo

That question wouldn't survive on StackOverflow! But I guess this isn't SO :P

Veera Venkata Avinash's photo

Rahul Bisht's photo

                                          var                      list                      = ['a',                      'b',                      'c'];                      var                      root = {};                      list.forEach((item) => {                      var                      current = {};   current[item] = {};                      var                      keys = Object.keys(current);                      var                      t = findRoot(root);   t[keys[0]] = current[keys[0]]; });                                              function                        findRoot                        (obj)                      {                      var                      keys = Object.keys(obj);                      if                      (keys.length ==                      0)                      return                      obj;                      var                      lastKey = keys[keys.length -                      1];                      return                      obj[lastKey]; }  console.log(root);                                      

Veera Venkata Avinash's photo

                                          var                      name = ["a","b","c","d"]                      var                      index = {}                      var                      root =                      index                        for(                          var                          i=0;i<name.length;i++){                      var                      char                      = name[i];     root[char] = {}     root = root[char]                      // on next iteration context will be                      // newly created object                      } console.log(index);                                      

How To Create A Set In Javascript

Source: https://hashnode.com/post/how-to-create-nested-child-objects-in-javascript-from-array-cj9tsc3we01m0uowu4pyuesy0

Posted by: nivensonst1959.blogspot.com

0 Response to "How To Create A Set In Javascript"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel