[英]Javascript code infinite loop
我正在創建一個函數,它接受一個值數組並返回一個只有唯一值的數組。 例如:
var strings = ["audi", "audi", "bmw", "bmw","bmw","bmw","audi","audi", "8-()"];
結果應該是:
alert( unique(strings) ); // audi, bmw, 8-()
我不明白為什么我的功能進入無限循環,有人可以幫忙嗎? 這是功能:
function unique(arr) {
var result = [];
result.push(arr[0]);
for (var i = 1; i < arr.length; i++) {
for (var j = 0; j < result.length; j++) {
if (result[j] != arr[i]) {
result.push(arr[i]);
}
}
}
return result;
}
不需要嵌套循環。 您可以使用Array.prototype.indexOf
或Array.prototype.includes
方法檢查結果的可用值。
var strings = ["audi", "audi", "bmw", "bmw", "bmw", "bmw", "audi", "audi", "8-()"]; function unique(arr) { var result = []; result.push(arr[0]); for (var i = 1; i < arr.length; i++) { if (result.indexOf(arr[i]) === -1) result.push(arr[i]); } return result; } console.log(unique(strings))
var strings = ["audi", "audi", "bmw", "bmw", "bmw", "bmw", "audi", "audi", "8-()"]; console.clear(); var result = strings.filter(function(s){ return this[s] ? false : (this[s] = true); }, Object.create(null)) console.log(result);
使用Set
和spread operators
屬於ES6,你可以使它更簡單,
var unique = src => [...new Set(src)]
順便說一句,你的邏輯錯了。 它不會遇到無限循環。 但它會給你一個不良的結果。
您可以更簡單:使用Array.reduce
var values = [1,2,3,4,5,5,5,5,5,6,6,6,62,2,2] function getUniq(array) { return array.reduce(function(u, value) { if (u.indexOf(value) < 0) u.push(value) return u; }, []) } console.log(getUniq(values))
您可以減少此時間的復雜性
var strings = ["audi", "audi", "bmw", "bmw","bmw","bmw","audi","audi", "8-()"];
var unique = [];
strings.forEach(function(str){
if (unique.indexOf(str) < 0) {
unique.push(str)
}
});
return unique;
您也可以使用Set
var strings = ["audi", "audi", "bmw", "bmw","bmw","bmw","audi","audi", "8-()"];
var uniq = new Set(strings);
// if you need in array
uniq = Array.from(uniq);
您也可以使用字典/哈希表。 然后總運行時應該是O(N),用於循環arr
一次:
function unique(arr) {
unique = {}
for(var i=0; i<arr.length; i++) {
unique[arr[i]]=true
}
return Object.keys(unique)
}
您可以稍微更改內部循環並使用found
的變量來檢查值是否在結果數組中。
還需要此變量來檢查值是否要推送到結果集。
此外,如果找到重復值,您可以使用break
來退出內部循環。
function unique(arr) { var result = [], found; result.push(arr[0]); for (var i = 1; i < arr.length; i++) { found = false; // initial set to false for (var j = 0; j < result.length; j++) { if (result[j] === arr[i]) { found = true; // set to true to skip push break; // exit loop } } found || result.push(arr[i]); // push only, if not found } return result; } var strings = ["audi", "audi", "bmw", "bmw", "bmw", "bmw", "audi", "audi", "8-()"]; console.log(unique(strings)); // audi, bmw, 8-()
一個較短的ES6提案,帶有Array#filter
和一個哈希表作為閉包。
function unique(arr) { return arr.filter((temp => a => !temp[a] && (temp[a] = true))(Object.create(null))); } var strings = ["audi", "audi", "bmw", "bmw", "bmw", "bmw", "audi", "audi", "8-()"]; console.log(unique(strings)); // audi, bmw, 8-()
另一種最快的方法,就是花2毫秒檢查性能
var dupEleArr = [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 20, 3, 3, 3, 32, 324, 5, 52];
var uniqueArr = dupEleArr.sort(function(a,b){
return a-b;
}).filter(function(ele,i,arr){
return arr.length > 3 ? arr[i] != arr[i+1] : (arr.length == 2) ? (arr[i] != arr[i+1]) : true;
});
push()將一個新對象推送到數組的開頭並將所有內容推回去!
讓我們在程序中查看數組的狀態:
arr = [A,B] result = [A] i = 1
j = 0 -> arr[i] = B and result[j] = A
so we use push: result = [B,A] and j++
j = 1 -> arr[i] = B and result[j] = A
so we use push: result = [B,B,A] and j++
j = 2 -> arr[i] = B and result[j] = A
so we use push: result = [B,B,B,A] and j++
您的數組不斷增加,檢查永遠不會失敗,因為您追加到數組的開頭而不是結尾。
但即使您將新項目添加到最后,也不會得到唯一的結果,因為您必須檢查結果中的每個元素,並且只有在沒有任何結果相同的情況下才應將新元素添加到結果數組中。
為了更好的解決方案看其他的答案- >使用設置有contains()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.