2

我知道我可以使用这个答案的变体来找出数组中有多少种不同类型的数据:

如何计算数组中某个元素的个数?

但是,我正在寻找的是是否有一种简单的方法来计算数组中有多少不同类型的数据:

我有可能有 0、1 或 2 作为值的数组

所以它可能是:

a = [1,2,0,1,1,1];

或者它们可能都相同但长度不同:

a = [1,1,1,1,1,1,1,1,1,1,1,1,1];

在javascript中,我想要一个函数,如果所有值都相同,则返回“1”,如果只有两个可能值的混合,则返回“2”,如果数组包含所有三个值,则返回“3”。

任何帮助表示赞赏。谢谢。

4

2 回答 2

3

简单的方法是保存一个找到值的映射,并记住每次添加它:Live Example | 直播源

function countUniques(a) {
    var valuesSeen = {};
    var count = 0;

    a.forEach(function(value) {
        if (!valuesSeen[value]) {
            ++count;
            valuesSeen[value] = true;
        }
    });
    return count;
}

(注意:使用 ES5 的forEach.如果您使用的是旧浏览器,则需要对其进行 shim,搜索“ES5 shim”以找到它的 shim。)

或者,如果您不喜欢与您一起工作的人,并且喜欢使用运算符而不是分支语句:Live Copy | 直播源

function countUniques(a) {
    var valuesSeen = {}, count = 0;

    a.forEach(function(value) {
        valuesSeen[value] || (++count,  valuesSeen[value] = true);
    });
    return count;
}
于 2013-06-29T16:53:56.527 回答
3

只是为了好玩,这里有一个“更时髦”(而且有点混淆)的解决方案.reduce,它不需要局部变量:

function countUniques(a) {
     return a.reduce(function(p, v) {
         p.c += !(v in p.s); p.s[v] = 1; return p;
     }, {c:0, s:{}}).c;
}

它在功能上与 TJC 的答案相同,不同之处在于valuesSeenandcount值作为对象传递,因为从元素的先前迭代传递 的p“先前”值等效于 TJC 的and is 。.reduce.p.ccountp.svaluesSeen

请注意,.reduce(like .forEach) 是一个 ES5 函数,它需要在旧浏览器上使用 shim。

于 2013-06-29T17:10:15.640 回答