JSFiddle: http://jsfiddle.net/3WdzL/1/
我需要将语言环境 JS 对象文件转换为扁平化版本,然后再转换回来:
原始区域设置对象:
var localeObj = {
toolbar: {
link: {
back: 'Back',
menu: 'Menu',
},
flatTest: 'something'
},
countries: [
["AF", "Afghanistan"],
["AX", "Åland Islands"],
['nested', [1, 2, 3, 4]],
["AL", "Albania"]
]
};
使用以下函数:
function flattenObj(obj) {
var flattenedObj = {};
var walk = function(obj, stringMap) {
for(k in obj) {
var computedKey = stringMap + (stringMap ? '.' + k : k);
if(typeof obj[k] !== 'object') {
flattenedObj[computedKey] = obj[k];
} else {
walk(obj[k], computedKey);
}
}
};
walk(obj, '');
return flattenedObj;
}
会产生一个扁平的物体:
{
toolbar.link.back: Back
toolbar.link.menu: Menu
toolbar.flatTest: something
countries.0.0: AF
countries.0.1: Afghanistan
countries.1.0: AX
countries.1.1: Åland Islands
countries.2.0: nested
countries.2.1.0: 1
countries.2.1.1: 2
countries.2.1.2: 3
countries.2.1.3: 4
countries.3.0: AL
countries.3.1: Albania
}
使用以下函数转换回来对于对象来说效果很好:
function deepenObj(obj) {
var deepenedObj = {}, tmp, parts, part;
for (var k in obj) {
tmp = deepenedObj;
parts = k.split('.');
var computedKey = parts.pop();
while (parts.length) {
part = parts.shift();
tmp = tmp[part] = tmp[part] || {};
}
tmp[computedKey] = obj[k];
}
return deepenedObj;
}
但是会为数组生成这样的结构:
region: {
country: {
0: {
0: 'AF',
1: 'Afghanistan'
},
...
2: {
0: 'nested',
1: {
0: 1,
1: 2,
3: 4,
4: 5
}
}
}
}
显然这不是数组想要的结果,而且我还无法想出一个安全、优雅甚至有效的解决方案。 PS 我很高兴以不同的方式将数组保存为字符串,如果它能让转换回来更容易。谢谢!
最佳答案
您应该跟踪对象是否实际上是数组:
var walk = function(obj, stringMap) {
if (Array.isArray(obj) {
for (var k = 0; k < obj.length; k++)
var computedKey = stringMap ? stringMap + ',' + k : k;
} else {
for (var k in obj) {
var computedKey = stringMap ? stringMap + '.' + k : k;
...
然后,深化时:
for (var k in obj) {
tmp = deepenedObj;
parts = ["."].concat(k.split(/([\.,])/));
var computedKey = parts.pop(), sign;
while (parts.length) {
sign = parts.shift();
part = !parts.length ? computedKey : parts.shift();
tmp = tmp[part] = tmp[part] || (sign === "," ? [] : {});
}
tmp[computedKey] = obj[k];
}
请注意,Array.isArray
可能是未定义
。您可以使用 obj instanceof Array 代替。
如果 localeObj
是对象文字而不是数组,则此解决方案有效,因为第一个点/逗号未保存在计算键中。如果需要,您可以修改该函数。
这里的技巧是使用 split
的不寻常行为,当与正则表达式一起使用时,它将捕获的组推送到拆分数组中,因此在每个关键部分之前都有适当的分隔符。
关于javascript - 在 JavaScript 中从扁平化字符串构造数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17026366/