66 lines
1.9 KiB
JavaScript
66 lines
1.9 KiB
JavaScript
function get(obj, path) {
|
|
if (obj == null)
|
|
return void 0;
|
|
let value = obj;
|
|
for (let i = 0; i < path.length; i++) {
|
|
if (value === void 0 || value[path[i]] === void 0)
|
|
return void 0;
|
|
if (value === null || value[path[i]] === null)
|
|
return null;
|
|
value = value[path[i]];
|
|
}
|
|
return value;
|
|
}
|
|
function set(obj, value, path) {
|
|
if (path.length === 0)
|
|
return value;
|
|
const idx = path[0];
|
|
if (path.length > 1) {
|
|
value = set(
|
|
typeof obj !== "object" || obj === null || !Object.prototype.hasOwnProperty.call(obj, idx) ? Number.isInteger(Number(path[1])) ? [] : {} : obj[idx],
|
|
value,
|
|
Array.prototype.slice.call(path, 1)
|
|
);
|
|
}
|
|
if (Number.isInteger(Number(idx)) && Array.isArray(obj))
|
|
return obj.slice()[idx];
|
|
return Object.assign({}, obj, { [idx]: value });
|
|
}
|
|
function unset(obj, path) {
|
|
if (obj == null || path.length === 0)
|
|
return obj;
|
|
if (path.length === 1) {
|
|
if (obj == null)
|
|
return obj;
|
|
if (Number.isInteger(path[0]) && Array.isArray(obj))
|
|
return Array.prototype.slice.call(obj, 0).splice(path[0], 1);
|
|
const result = {};
|
|
for (const p in obj)
|
|
result[p] = obj[p];
|
|
delete result[path[0]];
|
|
return result;
|
|
}
|
|
if (obj[path[0]] == null) {
|
|
if (Number.isInteger(path[0]) && Array.isArray(obj))
|
|
return Array.prototype.concat.call([], obj);
|
|
const result = {};
|
|
for (const p in obj)
|
|
result[p] = obj[p];
|
|
return result;
|
|
}
|
|
return set(
|
|
obj,
|
|
unset(
|
|
obj[path[0]],
|
|
Array.prototype.slice.call(path, 1)
|
|
),
|
|
[path[0]]
|
|
);
|
|
}
|
|
export function deepPick(obj, paths) {
|
|
return paths.map((p) => p.split(".")).map((p) => [p, get(obj, p)]).filter((t) => t[1] !== void 0).reduce((acc, cur) => set(acc, cur[1], cur[0]), {});
|
|
}
|
|
export function deepOmit(obj, paths) {
|
|
return paths.map((p) => p.split(".")).reduce((acc, cur) => unset(acc, cur), obj);
|
|
}
|