-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.

5
  • 3
    Hi there. Can you let us know what approaches you have tried? Where exactly are you stuck? Commented Apr 24, 2020 at 6:44
  • Let us know what you have done please, so we can assist with an answer. Commented Apr 24, 2020 at 6:49
  • @JasperZelf Updated with my code approach. Commented Apr 24, 2020 at 7:02
  • @NinaScholz Please reopen the question. I have updated my question.. Commented Apr 24, 2020 at 7: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 Commented Apr 24, 2020 at 9:12

1 Answer 1

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; }

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.