Вдохновленный ClojureScript assoc-in
( https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs#L5280), с помощью рекурсии:
/**
* Associate value (v) in object/array (m) at key/index (k).
* If m is falsy, use new object.
* Returns the updated object/array.
*/
function assoc(m, k, v) {
m = (m || {});
m[k] = v;
return m;
}
/**
* Associate value (v) in nested object/array (m) using sequence of keys (ks)
* to identify the path to the nested key/index.
* If one of the values in the nested object/array doesn't exist, it adds
* a new object.
*/
function assoc_in(m={}, [k, ...ks], v) {
return ks.length ? assoc(m, k, assoc_in(m[k], ks, v)) : assoc(m, k, v);
}
/**
* Associate value (v) in nested object/array (m) using key string notation (s)
* (e.g. "k1.k2").
*/
function set(m, s, v) {
ks = s.split(".");
return assoc_in(m, ks, v);
}
Примечание:
С обеспеченной реализацией,
assoc_in({"a": 1}, ["a", "b"], 2)
возвраты
{"a": 1}
я предпочел бы, чтобы она бросила ошибку в этом случае. При желании можно добавить, что регистрация assoc
для проверки m
является или объектом или массивом, и бросьте ошибку иначе.