[英]How do I refactor my code to reduce the amount of nested loops?
這是一個輔助函數,它將像對象這樣的數組轉換為實際數組,然后循環遍歷iterable,將列表中的每個值提供給回調函數:
var each = function(iterable, callback) {
iterable = Array.prototype.concat.apply([], iterable);
for(var i = 0; i < iterable.length; i++) {
callback.apply(iterable[i], [iterable[i], i]);
}
return iterable;
};
這里我使用前面提到的輔助函數來遍歷數組:
var found = [];
each(arguments, function(argument) {
each(argument.split(","), function(selector) {
each(handle(selector), function(element) {
if(found.indexOf(element) < 0) {
found.push(element);
}
});
});
});
第一個循環遍歷參數。 第二個循環拆分選擇器,第三個循環遍歷請求的元素,並將它們添加到found
數組(如果它們尚未添加)。
注意 : handle
函數接受選擇器(字符串)並使用document.querySelectorAll
返回元素列表。
這個腳本有效,但問題是可讀性和性能。
當有許多參數包含多個(~5-10)逗號分隔選擇器然后由handle
函數單獨處理時,會出現性能問題。
我通過使用類而不是id來修復此問題。
然后是可讀性的問題,我試圖通過移動第二環父循環之外來解決,但這需要更多的變量的創建,這讓正在發生變化,其中 ,唯一的區別each
回路是,這使得可讀性更差,鑒於有更多的代碼可供閱讀。
問題 :如何重構代碼以減少嵌套循環的數量?
還有,第一次循環是否必要? 如果我不使用它,我將如何遍歷參數以拆分它們以獲得每個單獨的選擇器? 我知道split
方法是String
類型,不能在數組上調用。
注意 :我使用的是vanilla JavaScript,不包括任何庫,框架或外部腳本。
您似乎希望收集出現在某些順序數據源中的許多值,例如
["A,B", "C,A,D", "A", "C,E,B"]
進入一組 (沒有重復),如
{"A", "B", "C", "D", "E"}
你可以在沒有任何第三方庫的情況下(不用擔心性能或可讀性)使用三個嵌套循環來做到這一點:
const s = new Set();
for (let x of arguments) {
for (let g of x.split(",")) {
for (let i of g) {
s.add(i);
}
}
}
從功能上來說,你可以將整個事情減少到:
new Set(arguments.join().split(','))
這假設您的任何選擇器當然沒有逗號。
這里的列表並沒有真正嵌套,因為你在三遍中完全處理了原始列表。 細分:
[ 'A,B', 'C,A,D', 'A', 'C,E,B' ]
'A,B,C,A,D,A,C,E,B'
[ 'A', 'B', 'C', 'A', 'D', 'A', 'C', 'E', 'B' ]
Set { 'A', 'B', 'C', 'D', 'E' }
我認為即使在循環情況下你也有線性復雜性,因為你實際上是在原始數組上進行三次傳遞。 並非每個過程都觸及每個元素,因此雖然它看起來像原始情況下的立方復雜性,但您應該沒問題 ,但如果事情看起來很糟糕,請考慮分析。
你可以加入然后resplit參數並使用三元運算符來減少行數:)
var found = [];
each(arguments.join(",").split(","), function(selector) {
each(handle(selector), function(element) {
return (found.indexOf(element) < 0) ? found.push(element) : null;
});
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.