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
}
使用以下func转换回来可以很好地处理对象:
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我很乐意将数组保存为不同的字符串,如果它使转换更容易。谢谢!
答案 0 :(得分:2)
如果对象实际上是一个数组,您应该跟踪:
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
可以是undefined
。您可以改为使用obj instanceof Array
。
如果localeObj
是对象文字而不是数组,则此解决方案有效,因为第一个点/逗号未保存在计算键中。如果需要,您可以修改该功能。
这里的技巧是使用split
的异常行为,当与正则表达式一起使用时,它会在分割数组中推送捕获的组,因此在每个关键部分之前都有适当的分隔符。
答案 1 :(得分:0)
使用JSON.stringify()
和JSON.parse()
:
var flattenedObj = JSON.stringify(localeObj);
vat deepenedObj = JSON.parse(flattenedObj);