【发布时间】:2010-02-09 10:38:32
【问题描述】:
请告诉我任何好的算法/代码来从数组中获取唯一值列表并计算它在数组中的出现次数。 (我正在使用 javascript)。
【问题讨论】:
标签: javascript arrays
请告诉我任何好的算法/代码来从数组中获取唯一值列表并计算它在数组中的出现次数。 (我正在使用 javascript)。
【问题讨论】:
标签: javascript arrays
将对象用作关联数组:
var histo = {}, val;
for (var i=0; i < arr.length; ++i) {
val = arr[i];
if (histo[val]) {
++histo[val];
} else {
histo[val] = 1;
}
}
这应该是最坏的 O(n*log(n)),取决于访问对象属性的时间。如果您只想要字符串,请遍历对象的属性:
for (val in histo) {...}
【讨论】:
对于从数组中去除重复项并返回具有唯一值的新数组的方法,您可能需要检查以下Array.unique implementation。由于 O(n2) 的复杂度,它肯定不是最快的算法,但对于小型未排序数组可以完成这项工作。
它是在 GPLv3 下获得许可的,所以我应该可以在这里粘贴实现:
// **************************************************************************
// Copyright 2007 - 2009 Tavs Dokkedahl
// Contact: http://www.jslab.dk/contact.php
//
// This file is part of the JSLab Standard Library (JSL) Program.
//
// JSL is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// any later version.
//
// JSL is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// ***************************************************************************
Array.prototype.unique =
function() {
var a = [];
var l = this.length;
for(var i=0; i<l; i++) {
for(var j=i+1; j<l; j++) {
if (this[i] === this[j]) // If this[i] is found later in the array
j = ++i;
}
a.push(this[i]);
}
return a;
};
您可以按如下方式使用它:
var myArray = new Array("b", "c", "b", "a", "b", "g", "a", "b");
myArray.unique(); // returns: ["c", "g", "a", "b"]
您可能需要调整以上内容以某种方式附加每个值的出现次数。
【讨论】:
一种直接的方法是遍历数组一次并计算哈希中的值
a = [11, 22, 33, 22, 11];
count = {}
for(var i = 0; i < a.length; i++)
count[a[i]] = (count[a[i]] || 0) + 1
“计数”是这样的 { 11: 2, 22: 2, 33: 1 }
对于排序数组,以下会更快
a = [11, 11, 11, 22, 33, 33, 33, 44];
a.sort()
uniq = [];
len = a.length
for(var i = 0; i < len;) {
for(var k = i; k < len && a[k] == a[i]; k++);
if(k == i + 1) uniq.push(a[i])
i = k
}
// here uniq contains elements that occur only once in a
【讨论】:
此方法适用于原始数组 - 字符串、数字、布尔值,
以及可以比较的对象(比如dom元素)
Array.prototype.frequency= function(){
var i= 0, ax, count, item, a1= this.slice(0);
while(i<a1.length){
count= 1;
item= a1[i];
ax= i+1;
while(ax<a1.length && (ax= a1.indexOf(item, ax))!= -1){
count+= 1;
a1.splice(ax, 1);
}
a1[i]+= ':'+count;
++i;
}
return a1;
}
var arr= 'jgeeitpbedoowknnlfiaetgetatetiiayolnoaaxtek'.split('');
var arrfreq= arr.frequency();
返回值按照数组中每个唯一元素的第一个实例的顺序。
您可以随意对其进行排序-从最高到最低频率排序:
arrfreq.sort(function(a, b){
a= a.split(':');
b= b.split(':');
if(a[1]== b[1]){
if(a[0]== b[0]) return 0;
return a[0]> b[0]? 1: -1;
}
return a[1]> b[1]? -1: 1;
});
arrfreq 现在返回(数组): ['e:7','t:6','a:5','i:4','o:4','n:3','g:2','k:2',' l:2','b:1','d:1','f:1','j:1','p:1','w:1','x:1','y: 1']
不能忽略 IE:
Array.prototype.indexOf= Array.prototype.indexOf ||
function(what, index){
index= index || 0;
var L= this.length;
while(index< L){
if(this[index]=== what) return index;
++index;
}
return -1;
}
【讨论】:
我知道这是旧帖子,但我一直在寻找一个简单的解决方案,所以我想我会将我的成果发布给仍在研究此问题的任何人
const test = [5, 3, 9, 5, 3, 5, 5]
//This function will return a new array of only the specified value
Array.prototype.unique = function(find) {
return this.filter(x => x == find)
}
//Usage
console.log(test.unique(5)) // returns [5,5,5,5]
//This Function will return the number of occurences in an array
Array.prototype.count = function(find) {
return this.filter(x => x == find).length
}
//Usage
console.log(test.count(5)) // returns 4
【讨论】: