Skip to content

Instantly share code, notes, and snippets.

@Raiondesu
Last active September 10, 2020 12:14
Show Gist options
  • Save Raiondesu/759425dede5b7ff38db51ea5a1fb8f11 to your computer and use it in GitHub Desktop.
Save Raiondesu/759425dede5b7ff38db51ea5a1fb8f11 to your computer and use it in GitHub Desktop.
Object path manipulators: simple get & set via a path w/o exceptions. Also works with numbered indecies (and nested arrays);

fromPath

const obj = {
  2: 3,
  very: {
    nested: {
      object: {
        here: '!'
      }
    }
  }
};

fromPath(obj, ''); // returns the obj itself
fromPath(obj, 'very.nested.object.here'); // '!'
fromPath(obj, 'very.nested.object'); // { here: '!' }
fromPath(obj, 2); // 3
fromPath(obj, 'very.bad.path.that.does.not.exist'); // undefined

fromPath(obj, ''); // returns the obj itself

assignToPath

const obj = {
  2: 3,
  very: {
    nested: {
      object: {
        here: '!'
      }
    }
  }
};

fromPath(obj, 2); // 3
assignToPath(obj, 2, 12); // obj[2] === 12 now
fromPath(obj, 2); // 12

assignToPath(obj, 'very.nested.object.here', '.');
fromPath(obj, 'very.nested.object.here'); // '.'

fromPath(obj, 'very.nested.object'); // { here: '.' }
assignToPath(obj, 'very.nested.object', '!');
fromPath(obj, 'very.nested.object'); // '!'

fromPath(obj, 'very.bad.path.that.does.not.exist'); // undefined
assignToPath(obj, 'very.bad.path.that.does.not.exist', 'really?');
console.log(obj); /* {
  2: 3,
  very: {
    bad: {
      path: {
        that: {
          does: {
            not: {
              exitst: 'really?'
            }
          }
        }
      }
    },
    nested: {
      object: '!'
    }
  }
} */
/**
* assignToPath
* Assigns a value to an object by a given path (usually string).
* If the path is invalid, silently creates the required path and assigns a value
*
* @param obj an object to get a value from.
* @param path to get a value by.
* @param value a value to assign.
* @param splitter to split the path by. Default is '.' ('obj.path.example')
*/
export function assignToPath(obj, path, value, splitter = '.') {
if (!path)
return obj;
const pathArr = (typeof path === 'string' && ~path.indexOf(splitter)) ? path.split(splitter) : [path];
const key = pathArr.pop()!;
const final = pathArr.length === 0 ?
obj : pathArr.reduce((o, i) => {
if (o === Object(o)) {
if (o[i] === undefined)
o[i] = {};
return o[i];
}
return o = {};
}, obj);
final[key] = value;
}
/**
* fromPath
* Returns a value from an object by a given path (usually string).
*
* @param obj an object to get a value from.
* @param path to get a value by.
* @param splitter to split the path by. Default is '.' ('obj.path.example')
* @returns a value from a given path. If a path is invalid - returns undefined.
*/
export function fromPath(obj, path, splitter = '.') {
if (!path)
return obj;
if (typeof path === 'number' || !~path.indexOf(splitter))
return obj[path];
return path.split(splitter).reduce((o, i) => (o === Object(o) ? o[i] : o), obj);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment