我正在创建一个函数,它接受一个值数组并返回一个只有唯一值的数组。例如:
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;
}
答案 0 :(得分:7)
不需要嵌套循环。您可以使用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))
&#13;
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);
&#13;
答案 1 :(得分:7)
您可以使Set
和spread operators
属于ES6非常简单,
var unique = src => [...new Set(src)]
顺便说一句,你的逻辑错了。它不会遇到无限循环。但它会给你带来不良后果。
答案 2 :(得分:4)
您可以更简单:使用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))
答案 3 :(得分:4)
您可以减少此
的时间复杂度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;
答案 4 :(得分:3)
您也可以使用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);
答案 5 :(得分:2)
你也可以使用字典/哈希表。然后总运行时间应为O(N),以便循环arr
一次:
function unique(arr) {
unique = {}
for(var i=0; i<arr.length; i++) {
unique[arr[i]]=true
}
return Object.keys(unique)
}
答案 6 :(得分:2)
您可以稍微更改内部循环并使用变量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-()
&#13;
较短的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-()
&#13;
答案 7 :(得分:0)
另一种最快的方式,它需要2毫秒check the performance
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;
});
答案 8 :(得分:0)
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++
你的数组不断增加,检查永远不会失败,因为你追加到数组的开头而不是结尾。
但即使您将新项目添加到最后,也不会得到独特的结果,因为您必须检查结果中的每个元素,并且只有在任何结果不相同的情况下才会检查应该将新元素添加到结果数组中。
要获得更好的解决方案,请参阅其他答案 - &gt;对contains()