Published
Edited
Jul 5, 2022
Insert cell
Insert cell
getset = ({

toPath(path) {
if (!path)
return [];
if (typeof path === 'string')
return path.split('.');
return path;
},

set(obj, path, value) {
path = this.toPath(path);
return doUpdate(obj, path, 0, value);
function doUpdate(obj, path, pos, value) {
if (pos >= path.length)
return value;
var name = path[pos];
var oldValue = obj[name];
var newValue = doUpdate(oldValue || {}, path, pos + 1, value);
if (oldValue !== newValue) {
obj = Object.assign({}, obj);
if (value === undefined && pos === path.length - 1) {
delete obj[name];
} else {
obj[name] = newValue;
}
}
return obj;
}
},

get(obj, path) {
path = this.toPath(path);
return doGet(obj, path, 0);
function doGet(obj, path, pos) {
if (pos === path.length || typeof obj !== 'object')
return obj;
var name = path[pos];
var value = obj[name];
if (pos < path.length - 1) {
return doGet(value, path, pos + 1);
} else {
return value;
}
}
},

_escape(segment) {
segment = segment ? segment.trim() : '';
return segment
.replace(/(["'])/gim, '\\$1')
.replace(/\r/gim, '\\r')
.replace(/\n/gim, '\\n');
},

// Generate value getter
newGetter(path) {
path = this.toPath(path);
let code = path.reduce((code, segment) => {
segment = this._escape(segment);
if (!segment) return code;
return `${code}["${segment}"]`;
}, '');
code = `try{ return obj${code}; } catch (err) { return undefined; }`;
return new Function(['obj'], `"use strict";\n${code}`);
},

// Generate value setter
newSetter(path) {
path = this.toPath(path);
let code = `var newObj = Object.assign({}, obj || {});\n`;
if (path.length) {
code += `var o = newObj;\n`;
for (let i = 0; i < path.length; i++) {
let segment = this._escape(path[i]);
if (!segment) continue ;
const next = `o["${segment}"]`;
if (i < path.length - 1) {
code += `o = ${next} = (typeof ${next} === "object")\n`
+ ` ? Object.assign({}, ${next})\n`
+ ` : {};\n`
} else {
code += `if (value === undefined) `;
code += `{\n delete ${next}; \n} else {\n ${next} = value; \n}\n`;
}
}
}
code += `return newObj;`
return new Function(['obj', 'value'], `"use strict";\n${code}`);
}

})
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more