function flatter(ob){
'use strict';
var f = {}, //return this
key;
for(key in ob) { //for each key
if (ob.hasOwnProperty(key)) {
if(typeof ob[key] === 'object') { //if value is object
//flatten this object again. Assign result to newOb
var newOb = flatter(ob[key]);
for(var x in newOb) {
f[key + '.' + x] = newOb[x];
}
} else {
f[key] = ob[key];
}
}
}
return f;
}
你可以像
function flatter(ob){
'use strict';
var f = {}, //return this object
key;
for(key in ob) { //for each key
if (ob.hasOwnProperty(key)) {
if(typeof ob[key] === 'object') { //if value is object
var newOb = (function (ob) {
'use strict';
var f = {}, //return this object
key;
for(key in ob) { //for each key
if (ob.hasOwnProperty(key)) {
if(typeof ob[key] === 'object') { //if value is object
var newOb = flatter(ob[key]);
for(var x in newOb) {
f[key + '.' + x] = newOb[x];
}
} else {
f[key] = ob[key];
}
}
}
return f;
}(ob[key]));
for(var x in newOb) {
f[key + '.' + x] = newOb[x];
}
} else {
f[key] = ob[key];
}
}
}
return f;
}
主要思想的東西翻譯這個代碼是每一個函數調用該函數的身體來代替。
對象本身是一個遞歸結構,因爲可以內容對象。如果給出
{
id: 12345,
name: 'John',
friends: [12346, 75645, 96768]
}
遞歸是不需要的。對象不包含任何對象,所以它可以在沒有額外的函數調用的情況下(通過平坦的方式)被拉長。如果給出
{
id: 12345,
name: {
first: 'John',
last: 'Doe'
},
friends: [12346, 75645, 96768]
}
然後對象包含對象作爲字段。所以你可以使用函數調用被函數體替換的函數。如果給出
{
id: 12345,
name: {
first: 'Helen',
last: {
beforeMarriage: 'Dobsky',
afterMarriage: 'Bobsky'
}
},
friends: [12346, 75645, 96768]
}
然後一個不能沒有3個函數調用。所以你可以複製三次函數體。但是,對象可以有[無限]非常深的結構。所以函數的嵌套體的數量是未知的。因此,不是將函數體嵌套到函數中,而是使用遞歸調用。
遞歸函數應至少有一個出口點,以避免無限遞歸
return f;
在我們的例子
。這個出口點可以達到,因爲對象中的字段數量是有限的。這不是解決任務的唯一方法。由於對象看起來像樹(一種)遞歸可以用堆棧來代替,這可以保留複雜的字段,並且在處理簡單的字段後返回到堆棧對象並在循環中對待它們。
堆棧實現。不漂亮,但作品)
function iflatter(input) {
'use strict';
var f = {}, //return this object
key,
stack = [],
ob,
prefix,
name;
stack.push(["", input]);
while (stack.length != 0) {
[prefix, ob] = stack.pop();
for(key in ob) { //for each key
if (ob.hasOwnProperty(key)) {
if (prefix !== "") {
name = prefix + "." + key;
} else {
name = key;
}
if(typeof ob[key] === 'object') {
stack.push([name, ob[key]]);
} else {
f[name] = ob[key];
}
}
}
}
return f;
}