繁体   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