Skip to content

Instantly share code, notes, and snippets.

@yhirose
Last active July 5, 2021 13:24
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 yhirose/1da10f614744a5b65fd920210e052e4a to your computer and use it in GitHub Desktop.
Save yhirose/1da10f614744a5b65fd920210e052e4a to your computer and use it in GitHub Desktop.
Immutable object update
// Based on 'Easy immutable objects in Javascript'
// https://spapas.github.io/2018/04/05/easy-immutable-objects/
const immutable_update = (obj, path, val) => {
if (!val) {
return path.reduce((obj, [path, val]) => immutable_update(obj, path, val), obj);
}
let parts = (typeof path === 'string' || path instanceof String) ? path.split('.') : path;
const cset = (obj, cidx, val) => {
let newval = val;
if (typeof val === "function") {
newval = val(obj[cidx]);
}
if (Array.isArray(obj)) {
return [...obj.slice(0, cidx * 1), newval, ...obj.slice(cidx * 1 + 1)];
} else {
return { ...obj, [cidx]: newval };
}
};
let pidx = parts[0];
if(parts.length == 1) {
return cset(obj, pidx, val);
} else {
let remaining = parts.slice(1);
return cset(obj, pidx, immutable_update(obj[pidx], remaining, val));
}
};
const state = {
'users': {
'results': [
{'name': 'Sera', 'groups': ['g1', 'g2', 'g3']},
{'name': 'John', 'groups': ['g1', 'g2', 'g3']},
{'name': 'Joe', 'groups': []}
],
'pagination': {
'total': 100,
'perpage': 5,
'number': 0
}
},
'groups': {
'results': [],
'total': 0
}
};
const path_and_value_list = [
['users.results.2.groups.0', 'aa'],
['users.results.0.name', (x) => x.toUpperCase()],
['users.pagination.total', (x) => x + 1],
['users.results.1.name', 'Jack']
];
console.log(state);
console.log(immutable_update(state, path_and_value_list));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment