在 JavaScript 中压缩对象层次结构
-
12-09-2019 - |
题
是否有一种通用方法将嵌套对象“压缩”到单个级别:
var myObj = {
a: "hello",
b: {
c: "world"
}
}
compress(myObj) == {
a: "hello",
b_c: "world"
}
我想会涉及一些递归,但我想我不需要在这里重新发明轮子......!?
解决方案
function flatten(obj, includePrototype, into, prefix) {
into = into || {};
prefix = prefix || "";
for (var k in obj) {
if (includePrototype || obj.hasOwnProperty(k)) {
var prop = obj[k];
if (prop && typeof prop === "object" &&
!(prop instanceof Date || prop instanceof RegExp)) {
flatten(prop, includePrototype, into, prefix + k + "_");
}
else {
into[prefix + k] = prop;
}
}
}
return into;
}
你可以包括成员继承的成员通过 true
进入第二个参数。
一些注意事项:
递归的对象不会的工作。例如:
var o = { a: "foo" }; o.b = o; flatten(o);
将recurse直到它抛出一个例外。
像ruquay的回答,这个翻出阵列要素只是喜欢正常的对象的性质。如果你想保持数组完整,添加"
|| prop instanceof Array
"为例外。如果你打电话给这个对象从一个不同窗口或框架、日期和定期的表情会不会被包括在内,因为
instanceof
不会正常工作。你可以解决这个问题通过取代它的默认toString方法是这样的:Object.prototype.toString.call(prop) === "[object Date]" Object.prototype.toString.call(prop) === "[object RegExp]" Object.prototype.toString.call(prop) === "[object Array]"
其他提示
下面是一个简单的一个,但要小心,B / C它会的不的工作瓦特/阵列和空值(B / C他们的typeof返回 “对象”)。
var flatten = function(obj, prefix) {
if(typeof prefix === "undefined") {
prefix = "";
}
var copy = {};
for (var p in obj) {
if(obj.hasOwnProperty(p)) {
if(typeof obj[p] === "object") {
var tmp = flatten(obj[p], p + "_");
for(var q in tmp) {
if(tmp.hasOwnProperty(q)) {
copy[prefix + q] = tmp[q];
}
}
}
else {
copy[prefix + p] = obj[p];
}
}
}
return copy;
}
var myObj = {
a: "level 1",
b: {
a: "level 2",
b: {
a: "level 3",
b: "level 3"
}
}
}
var flattened = flatten(myObj);
这是一个快速 咖啡脚本 版本基于 马修·克鲁姆利的回答 (我没有使用 includePrototype
因为我不需要它):
flatten = (obj, into = {}, prefix = '', sep = '_') ->
for own key, prop of obj
if typeof prop is 'object' and prop not instanceof Date and prop not instanceof RegExp
flatten prop, into, prefix + key + sep, sep
else
into[prefix + key] = prop
into
还有一个基本的非扁平版本,毫无疑问会因为重复的分隔符和其他类似的棘手问题而失败:
unflatten = (obj, into = {}, sep = '_') ->
for own key, prop of obj
subKeys = key.split sep
sub = into
sub = (sub[subKey] or= {}) for subKey in subKeys[...-1]
sub[subKeys.pop()] = prop
into
FWIW,我使用这些函数将对象图推入 Redis 哈希值, ,仅支持单一深度的键/值对。
不隶属于 StackOverflow