-1

I know this is probably easier than my brain is making it, but for some reason, I can't get this right:

I have an array looks like this:

["engine", "engine.car", "engine.car.driver", 
 "engine.car.passenger", "wheels", "wheels.tires"]

I want to transform above array into this object:

{
    engine : {
        car : {
            driver : undefined,
            passenger: undefined
        }
    },
    wheels : {
        tires: undefined
    }
 }

I'm using node 8.10.0.

mitch
  • 2,235
  • 3
  • 27
  • 46
kamii
  • 227
  • 2
  • 9
  • Did you try something out? Please post where you are stuck. – Sunil Chaudhary Jul 18 '18 at 16:48
  • Does the array always come sorted? For example, are all properties relating to engine going to be next to each other like in the example or can you have ["engine","wheels","engine.car","wheels.tires",...], because the solutions to this problem can vary. – user8463863 Jul 18 '18 at 16:49
  • no not at all, it can come in any order @user8463863 – kamii Jul 18 '18 at 16:56
  • @sunil I have nothing of real value to offer as far as "where I'm stuck". I know the solution is either a recursive algorithm which I am struggling with atm, or a way to access/create a nested property on a hash given the string path of it. It seems I've been marked redundant via the second solution, so that's great! No recursion! – kamii Jul 18 '18 at 16:58
  • `function transformArrayToObject ( array ) { var resultObject = {}, index, item; function _transform ( _array, tmpObject ) { if ( _array.length > 1 ) { tmpObject[_array[0]] = {}; return Object.assign(tmpObject, _transform(_array.slice(1), tmpObject[_array[0]])); } else return tmpObject[_array[0]] = void 0; } for ( index = 0; index < array.length; index += 1 ) { item = array[index].split('.'); resultObject[item[0]] = item.length > 1 ? _transform(item.slice(1), {}) : void 0; } return resultObject; }` – zhibirc Jul 19 '18 at 07:14
  • Are you looking for something like - https://codepen.io/nagasai/pen/djOYjP?editors=1010 which can be achieved using forEach and split() method – Naga Sai A Jul 19 '18 at 15:02

1 Answers1

-3

This is pretty straightforward with JavaScript and the eval functionality. Here is a quick example.

var arr = ["engine", "engine.car", "engine.car.driver",  "engine.car.passenger", "wheels", "wheels.tires"];
 
obj = {};
for(var i = 0; i < arr.length; i++)
 eval("obj." + arr[i] + " = {}");
  
console.log(obj);

Edit

Eval is not evil, most implementations of it are but this is a perfectly valid use of it as outlined in the comments below. If you have an issue with this answer please use the comments to let me know why so I can either update the answer or OP can get the help they need.

halfer
  • 19,824
  • 17
  • 99
  • 186
Adam H
  • 1,750
  • 1
  • 9
  • 24
  • 4
    using `eval` is a bad idea – Get Off My Lawn Jul 18 '18 at 16:56
  • @GetOffMyLawn Care to expand on that? – Adam H Jul 18 '18 at 17:20
  • https://stackoverflow.com/questions/86513/why-is-using-the-javascript-eval-function-a-bad-idea – Get Off My Lawn Jul 18 '18 at 17:55
  • @GetOffMyLawn '_Improper use of eval opens up your code for injection attacks_' this isn't data from user input so an injection attack doesn't apply here. '_Debugging can be more challenging (no line numbers, etc.)_' that's a fair argument. '_eval'd code executes slower (no opportunity to compile/cache eval'd code)_' Even it that thread he points out that isn't the issue it used to be. There are no absolutes, this is a perfectly fine use of eval. – Adam H Jul 18 '18 at 18:17
  • And how do you know this isn't user input? – Get Off My Lawn Jul 18 '18 at 18:23
  • @GetOffMyLawn because it's in an array – Adam H Jul 18 '18 at 18:24
  • Which could have been generated from user input... – Get Off My Lawn Jul 18 '18 at 18:27
  • Sure, it _could_ have but you just said 'using eval is a bad idea' you have no more information than I do so there is no way you can know if it is a 'bad idea' is all I'm saying. There are certainly valid times to use eval and this is potentially one of them. – Adam H Jul 18 '18 at 18:28