对于复杂字典类型对象的赋值与取值是很常用的,如果仅仅通过属性来进行数据访问,肯定是不够的。
这里我写了一个 Dict
对象,可以进行深度赋值与取值,接受一个对象,以 key,value
的形式表示将对象中 data
中的 key
对应的值改变成 value
。
其中 key
可以非常灵活,以数据路径的形式给出,如 array[2].message
,a.b.c.d
等。
直接上代码:
function Dict(data) {
var data = data || {};
Dict.prototype.set = function (key, value) {
if (!key) return false;
var keys = key.split('.'),
tmp = data,
len = keys.length,
i = 0,
k;
try {
for (k in keys) {
k = keys[k];
if ((patt = /^(\w)\[(\d+)\]$/.exec(k)) != null) {
if (!tmp[RegExp.$1]) {
tmp[RegExp.$1] = [];
}
if (!tmp[RegExp.$1][RegExp.$2]) {
tmp[RegExp.$1][RegExp.$2] = {}
}
if (++i == len) {
tmp[RegExp.$1][RegExp.$2] = value;
} else {
tmp = tmp[RegExp.$1][RegExp.$2];
}
} else {
if (!tmp[k]) {
tmp[k] = {}
}
if (++i == len) {
tmp[k] = value
} else {
tmp = tmp[k]
}
}
}
} catch (e) {
}
}
Dict.prototype.get = function (key) {
if (!key) return undefined;
var keys = key.split('.'),
tmp = data;
try {
for (var k in keys) {
k = keys[k];
if ((patt = /^(\w)\[(\d+)\]$/.exec(k)) != null) {
if (!tmp[RegExp.$1] || !tmp[RegExp.$1][RegExp.$2]) {
return undefined;
}
tmp = tmp[RegExp.$1][RegExp.$2];
} else {
tmp = tmp[k];
}
}
return tmp;
} catch (e) {
return undefined;
}
}
Dict.prototype.getObject = function () {
return data;
}
}
var dict = new Dict({a: 1});
// 1. 对于key存在且value为非对象类型,无法设置值
dict.set('a.b', 2);
console.log(dict.get('a.b')); // undefined
// 2. 使用 . 隔开的路径访问方式,可正常访问
dict.set('b.c.d', 2);
console.log(dict.get('b.c.d')); // 2
// 3. 使用数组下标访问方式,可正常访问
dict.set('b.c[1].d', 3);
console.log(dict.get('b.c[1].d')); // 3
// 4. 访问不存在的key,返回undefined
console.log(dict.get('b.d.a')); // undefined
// 5. 获取最终data的值
console.log(dict.getObject()); // {"a":1,"b":{"c":{"1":{"d":2},"d":2}}}