为了账号安全,请及时绑定邮箱和手机立即绑定

惯用地找到给定值在数组中出现的次数

惯用地找到给定值在数组中出现的次数

拉风的咖菲猫 2019-11-28 13:41:58
我有一个重复值的数组。我想找到任何给定值的出现次数。例如,如果我有一个这样定义的数组:var dataset = [2,2,4,2,6,4,7,8];,我想查找数组中某个值出现的次数。也就是说,程序应该显示如果我出现3次value 2,发生1次value 6,依此类推。什么是最惯用/优雅的方法?
查看完整描述

3 回答

?
HUX布斯

TA贡献1876条经验 获得超6个赞

reduce比filter它不仅仅为了计数而建立一个临时数组,在这里更合适。


var dataset = [2,2,4,2,6,4,7,8];

var search = 2;


var count = dataset.reduce(function(n, val) {

    return n + (val === search);

}, 0);


console.log(count);

在ES6中:


let count = dataset.reduce((n, x) => n + (x === search), 0);

请注意,使用自定义匹配谓词进行扩展很容易,例如,对具有特定属性的对象进行计数:


people = [

    {name: 'Mary', gender: 'girl'},

    {name: 'Paul', gender: 'boy'},

    {name: 'John', gender: 'boy'},

    {name: 'Lisa', gender: 'girl'},

    {name: 'Bill', gender: 'boy'},

    {name: 'Maklatura', gender: 'girl'}

]


var numBoys = people.reduce(function (n, person) {

    return n + (person.gender == 'boy');

}, 0);


console.log(numBoys);

{x:count of xs}在javascript中,对所有项目进行计数(即使对象成为对象)非常复杂,因为对象键只能是字符串,因此无法可靠地对具有混合类型的数组进行计数。不过,以下简单的解决方案在大多数情况下仍然可以正常使用:


count = function (ary, classifier) {

    classifier = classifier || String;

    return ary.reduce(function (counter, item) {

        var p = classifier(item);

        counter[p] = counter.hasOwnProperty(p) ? counter[p] + 1 : 1;

        return counter;

    }, {})

};


people = [

    {name: 'Mary', gender: 'girl'},

    {name: 'Paul', gender: 'boy'},

    {name: 'John', gender: 'boy'},

    {name: 'Lisa', gender: 'girl'},

    {name: 'Bill', gender: 'boy'},

    {name: 'Maklatura', gender: 'girl'}

];


// If you don't provide a `classifier` this simply counts different elements:


cc = count([1, 2, 2, 2, 3, 1]);

console.log(cc);


// With a `classifier` you can group elements by specific property:


countByGender = count(people, function (item) {

    return item.gender

});

console.log(countByGender);

在ES6中,您可以使用Map对象可靠地计数任意类型的对象。


class Counter extends Map {

    constructor(iter, key=null) {

        super();

        this.key = key || (x => x);

        for (let x of iter) {

            this.add(x);

        }

    }

    add(x) {

      x = this.key(x);

      this.set(x, (this.get(x) || 0) + 1);

    }

}


// again, with no classifier just count distinct elements


results = new Counter([1, 2, 3, 1, 2, 3, 1, 2, 2]);

for (let [number, times] of results.entries())

    console.log('%s occurs %s times', number, times);



// counting objects


people = [

    {name: 'Mary', gender: 'girl'},

    {name: 'John', gender: 'boy'},

    {name: 'Lisa', gender: 'girl'},

    {name: 'Bill', gender: 'boy'},

    {name: 'Maklatura', gender: 'girl'}

];



chessChampions = {

    2010: people[0],

    2012: people[0],

    2013: people[2],

    2014: people[0],

    2015: people[2],

};


results = new Counter(Object.values(chessChampions));

for (let [person, times] of results.entries())

    console.log('%s won %s times', person.name, times);


// you can also provide a classifier as in the above


byGender = new Counter(people, x => x.gender);

for (let g of ['boy', 'girl'])

   console.log("there are %s %ss", byGender.get(g), g);

的类型感知实现Counter可以如下所示(Typescript):


type CounterKey = string | boolean | number;


interface CounterKeyFunc<T> {

    (item: T): CounterKey;

}


class Counter<T> extends Map<CounterKey, number> {

    key: CounterKeyFunc<T>;


    constructor(items: Iterable<T>, key: CounterKeyFunc<T>) {

        super();

        this.key = key;

        for (let it of items) {

            this.add(it);

        }

    }


    add(it: T) {

        let k = this.key(it);

        this.set(k, (this.get(k) || 0) + 1);

    }

}


// example:


interface Person {

    name: string;

    gender: string;

}



let people: Person[] = [

    {name: 'Mary', gender: 'girl'},

    {name: 'John', gender: 'boy'},

    {name: 'Lisa', gender: 'girl'},

    {name: 'Bill', gender: 'boy'},

    {name: 'Maklatura', gender: 'girl'}

];



let byGender = new Counter(people, (p: Person) => p.gender);


for (let g of ['boy', 'girl'])

    console.log("there are %s %ss", byGender.get(g), g);


查看完整回答
反对 回复 2019-11-28
?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

较新的浏览器仅由于使用 Array.filter


var dataset = [2,2,4,2,6,4,7,8];

var search = 2;

var occurrences = dataset.filter(function(val) {

    return val === search;

}).length;

console.log(occurrences); // 3


查看完整回答
反对 回复 2019-11-28
?
慕雪6442864

TA贡献1812条经验 获得超5个赞

这是一次显示所有计数的一种方法:


var dataset = [2, 2, 4, 2, 6, 4, 7, 8];

var counts = {}, i, value;

for (i = 0; i < dataset.length; i++) {

    value = dataset[i];

    if (typeof counts[value] === "undefined") {

        counts[value] = 1;

    } else {

        counts[value]++;

    }

}

console.log(counts);

// Object {

//    2: 3,

//    4: 2,

//    6: 1,

//    7: 1,

//    8: 1

//}


查看完整回答
反对 回复 2019-11-28
  • 3 回答
  • 0 关注
  • 290 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信