Skip to content

Instantly share code, notes, and snippets.

@matiaslopezd
Last active June 14, 2021 20:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matiaslopezd/d8753b0b095ce1734d8de05e9c7cd556 to your computer and use it in GitHub Desktop.
Save matiaslopezd/d8753b0b095ce1734d8de05e9c7cd556 to your computer and use it in GitHub Desktop.
Read and set object by string path
Object.prototype.stringGet = function(string, object = this) {
string = string.replace(/\[(\w+)]/g, '.$1'); // convert indexes to properties
string = string.replace(/^\./, ''); // strip a leading dot
const array = string.split('.');
array.forEach((key) => {
if (key in object) object = object[key];
});
return object;
}
/*!
* Add items to an object at a specific path
* (c) 2021 Chris Ferdinandi, MIT License, https://gomakethings.com
* @param {Object} obj The object
* @param {String|Array} path The path to assign the value to
* @param {*} val The value to assign
*/
Object.prototype.stringSet = function (path, val, obj = this) {
/**
* If the path is a string, convert it to an array
* @param {String|Array} path The path
* @return {Array} The path array
*/
function stringToPath (path) {
// If the path isn't a string, return it
if (typeof path !== 'string') return path;
// Create new array
let output = [];
// Split to an array with dot notation
path.split('.').forEach(function (item) {
// Split to an array with bracket notation
item.split(/\[([^}]+)]/g).forEach(function (key) {
// Push to the new array
if (key.length > 0) output.push(key);
});
});
return output;
}
// Convert the path to an array if not already
path = stringToPath(path);
// Cache the path length and current spot in the object
let length = path.length;
let current = obj;
// Loop through the path
path.forEach(function (key, index) {
// Check if the assigned key should be an array
let isArray = key.slice(-2) === '[]';
// If so, get the true key name by removing the trailing []
key = isArray ? key.slice(0, -2) : key;
// If the key should be an array and isn't, create an array
if (isArray && !Array.isArray(current[key])) current[key] = [];
// If this is the last item in the loop, assign the value
if (index === length -1) {
// If it's an array, push the value
// Otherwise, assign it
if (isArray) current[key].push(val);
else current[key] = val;
}
// Otherwise, update the current place in the object
else {
// If the key doesn't exist, create it
if (!current[key]) current[key] = {};
// Update the current place in the object
current = current[key];
}
});
}
Object.prototype.stringGet=function(t,e=this){return(t=(t=t.replace(/\[(\w+)]/g,".$1")).replace(/^\./,"")).split(".").forEach(t=>{t in e&&(e=e[t])}),e},Object.prototype.stringSet=function(t,e,n=this){let r=(t=function(t){if("string"!=typeof t)return t;let e=[];return t.split(".").forEach(function(t){t.split(/\[([^}]+)]/g).forEach(function(t){t.length>0&&e.push(t)})}),e}(t)).length,i=n;t.forEach(function(t,n){let c="[]"===t.slice(-2);t=c?t.slice(0,-2):t,c&&!Array.isArray(i[t])&&(i[t]=[]),n===r-1?c?i[t].push(e):i[t]=e:(i[t]||(i[t]={}),i=i[t])})};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment