Lee*_*eem 119 javascript
如果我有一个数组[1, 2, 3, 5, 2, 8, 9, 2]
,我想检查2
数组中有多少个.在不使用for
循环循环的情况下,在JavaScript中执行此操作的最优雅方法是什么?
nin*_*cko 227
[ 这个答案有点过时了:阅读编辑 ]
打个招呼给您的朋友:map
和filter
和reduce
和forEach
和every
等.
(我偶尔会在javascript中编写for循环,因为缺少块级别的范围,所以如果你需要捕获或克隆你的迭代索引或值,你必须使用一个函数作为循环的主体.For-loops一般来说效率更高,但有时你需要一个闭包.)
最可读的方式:
[....].filter(x => x==2).length
Run Code Online (Sandbox Code Playgroud)
以下是更节省空间(O(1)而不是O(N)),但我不确定您可以在时间方面支付多少利益/罚款(不超过自您访问以来的常数因素)每个元素恰好一次):
[....].reduce((total,x) => (x==2 ? total+1 : total), 0)
Run Code Online (Sandbox Code Playgroud)
(如果你需要优化这段特殊的代码,在某些浏览器上for循环可能会更快......你可以在jsperf.com上测试一些东西.)
然后,您可以优雅并将其转换为原型函数:
[1, 2, 3, 5, 2, 8, 9, 2].count(2)
Run Code Online (Sandbox Code Playgroud)
像这样:
Object.defineProperties(Array.prototype, {
count: {
value: function(value) {
return this.filter(x => x==value).length;
}
}
});
Run Code Online (Sandbox Code Playgroud)
你也可以在上面的属性定义中坚持常规的旧的for-loop技术(参见其他答案)(再次,这可能会更快).
2017编辑:
哎呀,这个答案比正确答案更受欢迎.实际上,只需使用接受的答案.虽然这个答案可能很可爱,但js编译器可能不会(或不能因为规范)优化这些情况.所以你应该写一个简单的for循环:
Object.defineProperties(Array.prototype, {
count: {
value: function(query) {
/*
Counts number of occurrences of query in array, an integer >= 0
Uses the javascript == notion of equality.
*/
var count = 0;
for(let i=0; i<this.length; i++)
if (this[i]==query)
count++;
return count;
}
}
});
Run Code Online (Sandbox Code Playgroud)
您可以定义.filter(function(x){return x==2}).length
使用.countStrictEq(...)
相等概念的版本.平等的概念可能对你正在做的事情很重要!(例如===
,因为javascript中的数字如'4'== 4 ...因此调用它[1,10,3,'10'].count(10)==2
或.countEq
强调它使用.countNonstrict
运算符.)
还要考虑使用自己的多集数据结构(例如像python的' ==
')来避免首先进行计数.
class Multiset extends Map {
constructor(...args) {
super(...args);
}
add(elem) {
if (!this.has(elem))
this.set(elem, 1);
else
this.set(elem, this.get(elem)+1);
}
remove(elem) {
var count = this.has(elem) ? this.get(elem) : 0;
if (count>1) {
this.set(elem, count-1);
} else if (count==1) {
this.delete(elem);
} else if (count==0)
throw `tried to remove element ${elem} of type ${typeof elem} from Multiset, but does not exist in Multiset (count is 0 and cannot go negative)`;
// alternatively do nothing {}
}
}
Run Code Online (Sandbox Code Playgroud)
演示:
> counts = new Multiset([['a',1],['b',3]])
Map(2) {"a" => 1, "b" => 3}
> counts.add('c')
> counts
Map(3) {"a" => 1, "b" => 3, "c" => 1}
> counts.remove('a')
> counts
Map(2) {"b" => 3, "c" => 1}
> counts.remove('a')
Uncaught tried to remove element a of type string from Multiset, but does not exist in Multiset (count is 0 and cannot go negative)
Run Code Online (Sandbox Code Playgroud)
旁注:虽然,如果你仍然想要功能编程方式(或者一次性使用而不重写Array.prototype),你现在可以更加简洁地编写它collections.Counter
.如果你关心性能,请注意虽然这是渐进式的与for-loop(O(N)时间)相同的性能,但它可能需要O(N)额外的内存(而不是O(1)内存),因为它几乎会当然会生成一个中间数组,然后计算该中间数组的元素.
Tho*_*sen 74
非常简单:
var count = 0;
for(var i = 0; i < array.length; ++i){
if(array[i] == 2)
count++;
}
Run Code Online (Sandbox Code Playgroud)
小智 53
2017: 如果有人仍然对这个问题感兴趣,我的解决方案如下:
const arrayToCount = [1, 2, 3, 5, 2, 8, 9, 2];
const result = arrayToCount.filter(i => i === 2).length;
console.log('number of the found elements: ' + result);
Run Code Online (Sandbox Code Playgroud)
Han*_*son 44
ES6更新到JS:
// Let has local scope
let array = [1, 2, 3, 5, 2, 8, 9, 2]
// Functional filter with an Arrow function
array.filter(x => x === 2).length // -> 3
Run Code Online (Sandbox Code Playgroud)
JS中的以下一致箭头函数(lambda函数):
(x) => {
const k = 2
return k * x
}
Run Code Online (Sandbox Code Playgroud)
可以简化为单个输入的简洁形式:
x => 2 * x
Run Code Online (Sandbox Code Playgroud)
其中return
的暗示.
这是在 O(N) 中获取所有数组项计数的 ES2017+ 方法:
const arr = [1, 2, 3, 5, 2, 8, 9, 2];
const counts = {};
arr.forEach((el) => {
counts[el] = counts[el] ? (counts[el] += 1) : 1;
});
Run Code Online (Sandbox Code Playgroud)
您还可以选择对输出进行排序:
const countsSorted = Object.entries(counts).sort(([_, a], [__, b]) => a - b);
Run Code Online (Sandbox Code Playgroud)
console.log(countsSorted) 用于您的示例数组:
[
[ '2', 3 ],
[ '1', 1 ],
[ '3', 1 ],
[ '5', 1 ],
[ '8', 1 ],
[ '9', 1 ]
]
Run Code Online (Sandbox Code Playgroud)
如果您使用lodash或下划线,_.countBy方法将提供由数组中的每个值键入的聚合总计对象.如果您只需要计算一个值,则可以将其转换为单行:
_.countBy(['foo', 'foo', 'bar'])['foo']; // 2
Run Code Online (Sandbox Code Playgroud)
这也适用于数字数组.你的例子的单行将是:
_.countBy([1, 2, 3, 5, 2, 8, 9, 2])[2]; // 3
Run Code Online (Sandbox Code Playgroud)
我能想到的最奇怪的方法是:
(a.length-(' '+a.join(' ')+' ').split(' '+n+' ').join(' ').match(/ /g).length)+1
Run Code Online (Sandbox Code Playgroud)
在哪里:
我的建议是,使用 while 或 for 循环;-)
归档时间: |
|
查看次数: |
315858 次 |
最近记录: |