簡體   English   中英

Javascript代碼無限循環

[英]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.indexOfArray.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)) 

BTW廚師建議:

 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); 

使用Setspread 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)
}   

的jsfiddle

您可以稍微更改內部循環並使用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;
});

檢查jsfiddle

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM