-2

I have been given two arrays:-

var keys = ['a.b', 'a.c.d', 'a.e', 'h[0]'];
var values = [10, 20, {}, 40];

The output that I want is:-

{
    a: { 
         b: 10, 
         c: {
            d: 20
         }, 
         e: {}
    },
    h: [40]
}

What I have tried so far is

let constructObject = (keys, values) => {
    let output = {};
    for(let i = 0; i<keys.length; i++) {
        let props = keys[i].split('.');
        for(let j=0; j<props.length;j++) {
            if(props.length > (j+ 1)) {
                if(output[props[j]] == undefined) {
                  output[props[j]] = {};
                }
            } else {
              output[props[j]] = values[i];
            }
        }
    }
    return output;
}

The above code is not nesting deeper. I tried to store nested level key also using for loop but could not get any way to store keys, As javascript only gives way to store value not nested level keys.

  • 3
    Hi there. Can you let us know what approaches you have tried? Where exactly are you stuck? – JasperZelf Apr 24 '20 at 06:44
  • Let us know what you have done please, so we can assist with an answer. – Ryan Apr 24 '20 at 06:49
  • @JasperZelf Updated with my code approach. – Ayush Kumar Apr 24 '20 at 07:02
  • @NinaScholz Please reopen the question. I have updated my question.. – Ayush Kumar Apr 24 '20 at 07:07
  • I haven't found a dupe that also can handle arrays, but the dupe targets from this question has both: creating an object from strings/paths (w/o arrays) and settings properties (w/ arrays) -> [Dynamically updating a JavaScript object from a string path](https://stackoverflow.com/questions/15092912/dynamically-updating-a-javascript-object-from-a-string-path) – Andreas Apr 24 '20 at 09:12

1 Answers1

1

You could separate the pathes into smaller parts, like properties and indices and build new object by respecting the next key and decide if an array or an object has to be taken.

function setValue(target, keys, value) {
    const
        isWrapped = s => s.startsWith('[') && s.endsWith(']'),
        unwrap = s => isWrapped(s) ? s.slice(1, -1) : s,
        path = keys.match(/\[[^\]+]\]|[^\.\[\]]+/g),
        last = path.pop();

    path
        .reduce((o, k, i, { [i + 1]: next = last }) =>
            o[unwrap(k)] = o[unwrap(k)] || (isWrapped(next) ? [] : {}), target)
        [unwrap(last)] = value;
}

var keys = ['a.b', 'a.c.d', 'a.e', 'h[0]'],
    values = [10, 20, {}, 40],
    i,
    l = keys.length,
    result = {};

for (i = 0; i < l; i++) setValue(result, keys[i], values[i]);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392