Last active
February 23, 2021 18:23
-
-
Save xialvjun/6c23f0cd278e1ab81226b1b32a1af1bf to your computer and use it in GitHub Desktop.
immutable version of lodash/set
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/lodash/lodash/issues/1696 | |
import {clone, setWith, curry} from 'lodash/fp'; | |
// export const setIn = curry((path, value, obj) => | |
// setWith(clone, path, value, clone(obj)), | |
// ); | |
export const setIn = curry((obj, path, value) => | |
setWith(clone, path, value, clone(obj)), | |
); | |
// https://github.com/lodash/lodash/issues/1696#issuecomment-353016126 | |
// f you're using TypeScript, you should consider utilizing some standalone typing-aware "immutable set" library, | |
// like monolite(https://github.com/kube/monolite) or immutable-assign(https://github.com/engineforce/ImmutableAssign). | |
// ! 上面的 setIn 会有问题:在遇到 setIn({ a: { b: 1, c: null }, d: "xxx" }, 'a.c.e', 2) => 对象未发生变化,即它无法影响 null | |
// 于是自己写了一个 setpath | |
export const setpath = (obj, path, value) => { | |
const paths = path.split(/[\.\[\]\'\"]/g).map(s => parseInt(s) || s.trim()).filter(v => v!==''); | |
function set(obj, paths, value) { | |
if (paths.length === 0) { | |
return value; | |
} | |
if (paths.length === 1) { | |
const paths_0 = paths[0]; | |
if (paths_0 > -1) { | |
const clone = (obj || []).slice(); | |
clone[paths_0] = value; | |
return clone; | |
} | |
return Object.assign({}, obj, { [paths_0 + '']: value }); | |
} | |
const tail = set(get(obj, paths.slice(0, -1)), paths.slice(-1), value); | |
return set(obj, paths.slice(0, -1), tail); | |
} | |
return set(obj, paths, value); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment