由於被@Jonathan評論的問題是,你用一個計數器i
未在函數中聲明,因此全球性的。其結果是遞歸調用將改變呼叫者的i
等
function steamrollArray(arr) {
// I'm a steamroller, baby
var flat = [];
for(var i=0; i < arr.length; i++){
if(Array.isArray(arr[i])){
flat = flat.concat(steamrollArray(arr[i]));
} else {
flat.push(arr[i]);
}
} // end of the for loop
return flat;
}
的第二個挑戰是但使代碼在時間和存儲器的效率更高。這可以通過將列表結構的數量限制爲1來完成。您可以通過使用一個稱爲累加器的概念來完成此操作:通過遞歸過程更新的變量。首先,我們需要初始化變量:
function steamrollArray(arr) {
return steamer(arr,[]);
}
在這種情況下,累加器是結果,以及,和我們初始化該結果作爲一個空數組。顯然,我們還需要實現steamer
功能:
function steamer (arr,target) {
if(Array.isArray(arr)) {
var n = arr.length;
for(var i = 0; i < n; i++) {
steamer(arr[i],target);
}
} else {
target.push(arr);
}
return target;
}
什麼人做的是傳遞目標通過陣列樹的遞歸枚舉。如果該值成爲標量(Array.isArray
返回false
),我們將該元素添加到target
的末尾;否則我們執行遞歸調用。
此功能所做的最後一件事情是在初始steamer
調用target
將填充嵌套列表中的所有元素後返回target
。
優點是我們不需要昂貴的concat
函數,但只能使用push
函數O(n)次。如果我們抽象構建一個數組所需的處理時間(假設push
工作在O(1)時間),算法現在可以在O(n)時間和內存中使用n列表中的葉數樹。
數組可以任意深嵌套嗎? –
是的,它可以! 爲什麼? –
'var i = 0'。 [沒有'var','i'是一個全局變量](http://stackoverflow.com/questions/1470488/what-is-the-function-of-the-var-keyword-and-when-to-use因此每次調用'steamrollArray'都會共享並修改它。 –