0

I am trying to convert a string into a delimited object key but I need some assistance on how to iterate over the length of the array and join accordingly.

SET('my.delimited.string.of.unknown.length')

const SET = key => (state, val) => { 
        if(key.indexOf('.') !== -1) {
            let array = key.split(".")
            for (var i = 0; i < array.length; i++) {
                  // what should I do here?
            }
            // desired output based on array length
            // state[ array[0] ][ array[1] ] = val
            // state.my.delimited.string.of.unknown.length = val
        }
}
master00
  • 141
  • 2
  • 12

3 Answers3

1

One of those very rare usecases for reduce:

  const keys = key.split(".");
  const prop = keys.pop();
  keys.reduce((acc, key) => acc[key], state)[prop] = val;

For sure that could also be done with a for loop:

 let array = key.split("."), acc = state;
 for (var i = 0; i < array.length - 1; i++) {
   acc = acc[ array[i] ];
 }
 acc[ array.pop() ] = val;
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
0

For setting a value, you could split the path and reduce the path by walking the given object. If no object exist, create a new property with the name. Later assign the value.

function setValue(object, path, value) {
    var keys = path.split('.'),
        last = keys.pop();

    keys.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value;
}

var test = {};
setValue(test, "first.deep.property", 1);
setValue(test, "and.another.deep.property", 20);
console.log(test);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

You could also do this with a single Array.reduce:

const makeObject = (arr, val, obj={}) => {
  arr.split('.').reduce((r,c,i,a) => r[c] = i == a.length-1 ? val : {}, obj)
  return obj
}

console.log(makeObject("first.deep.property", 1))
console.log(makeObject("and.another.deep.property", 20))
Akrion
  • 18,117
  • 1
  • 34
  • 54