How can i access and change a value in an object with an array of keys

Viewed 74
const object = {
    key1: 'example_key1',
    key2: {
        key3: 'example_key2'
    }
}

const string = 'key1'
const array = ['key2', 'key3']

object[string] = 'foo' // Work
object[array] = 'bar' // Dont work

How can I access and change the object with the array of keys?

I have tried loadash.get but it can only get values not change them.

4 Answers

You need to do something like the following:

function set(obj, path, value) {
  var schema = obj
  var len = path.length
  for(var i = 0; i < len - 1; i++) {
    var elem = path[i]
    if (!schema[elem] ) schema[elem] = {}
    schema = schema[elem]
  }

  schema[path[len-1]] = value
}

And then you could use it in the following way:

set(object, array, 'someText')

With a function like the above set you can update an object passing an array of nested keys and the new value.

You could do something like:

const object = {
    key1: 'example_key1',
    key2: {
        key3: 'example_key2'
    }
}

const string = 'key1'
const array = ['key2', 'key3']

console.log(object[array[0]][array[1]])

EDIT

First solution is static. Below solution is more dynamic:

const object = {
    key1: 'example_key1',
    key2: {
        key3: 'example_key2'
    }
}

const object2 = {
    key1: 'example_key1',
    key2: {
        key3: {
           key4: "example_key3"
        }
    }
}


const string = 'key1'
const array = ['key2', 'key3']

let nestedObj = undefined;
array.forEach(val => {
   if (nestedObj) nestedObj = nestedObj[val];
   else nestedObj = object[val];
})
console.log(nestedObj)

const array2 = ['key2', 'key3', 'key4']

let nestedObj2 = undefined;
array2.forEach(val => {
   if (nestedObj2) nestedObj2 = nestedObj2[val];
   else nestedObj2 = object2[val];
})
console.log(nestedObj2)

You can create a recursive function and and check if the key from the object exist in the array, if so then change the key value in the object

const object = {
  key1: 'example_key1',
  key2: {
    key3: 'example_key2'
  },
  key3: 'someVal'
}

const array = ['key2', 'key3']

function doRecursion(obj) {
  for (let keys in obj) {
    if (array.includes(keys)) {
      console.log(typeof obj[keys])
      if (typeof obj[keys] === 'object') {
        doRecursion(obj[keys])
      } else {
        obj[keys] = 'bar';
      }
    } else {
      console.log(keys)
    }

  }
  return obj
};

console.log(doRecursion(object));

I think here recurtion will make things easier

function get(obj, keys) {
  if(typeof keys === 'string') {
    return obj[keys];
  }
  const key = keys.shift();
  return keys.length ? get(obj[key], keys) : obj[key];
}

const object1 = {
    key1: 'example_key1',
    key2: {
        key3: 'example_key2'
    }
}

const object2 = {
    key1: 'example_key1',
    key2: {
        key3: {
           key4: "example_key3"
        }
    }
}

const string = 'key1'
const array1 = ['key2', 'key3'];
const array2 = ['key2', 'key3', 'key4'];

console.log(get(object1, string));
console.log(get(object1, array1));
console.log(get(object2, array2));

Related