我正在寻找一种优雅的方法来确定哪个元素出现次数最高(模式) 在 JavaScript 数组中。
例如,
['pear', 'apple', 'orange', 'apple']
'apple'
元素是最常见的元素。
I'm looking for an elegant way of determining which element has the highest occurrence (mode) in a JavaScript array.
For example, in
['pear', 'apple', 'orange', 'apple']
the 'apple'
element is the most frequent one.
发布评论
评论(30)
这只是模式。 这是一个
快速、未优化的解决方案。 应该是O(n)。This is just the mode. Here's a
quick, non-optimizedsolution. It should be O(n).自 2009 年以来 javascript 有了一些发展 - 我想我应该添加另一个选项。 我不太关心效率,直到它实际上成为一个问题,所以我对“优雅”代码的定义(如OP规定的)有利于可读性 - 这当然是主观的......
在这个特定的例子中,如果集合中的两个或多个元素出现相同的次数,则将返回数组中最新出现的一个。 还值得指出的是,它会修改您的原始数组 - 如果您愿意,可以使用
Array.slice
预先调用。编辑:使用一些ES6更新了示例粗箭头 因为 2015 发生了,我认为它们看起来很漂亮......如果您担心向后兼容性,您可以在 修订历史记录。
There have been some developments in javascript since 2009 - I thought I'd add another option. I'm less concerned with efficiency until it's actually a problem so my definition of "elegant" code (as stipulated by the OP) favours readability - which is of course subjective...
In this particular example, should two or more elements of the set have equal occurrences then the one that appears latest in the array will be returned. It's also worth pointing out that it will modify your original array - which can be prevented if you wish with an
Array.slice
call beforehand.Edit: updated the example with some ES6 fat arrows because 2015 happened and I think they look pretty... If you are concerned with backwards compatibility you can find this in the revision history.
根据
George Jempty
要求算法考虑平局,我提出了Matthew Flaschen
算法的修改版本。现在将返回一个字符串,其中模式元素由
&
符号分隔。 收到结果后,可以将其拆分为&
元素,这样您就拥有了模式。另一种选择是返回模式元素数组,如下所示:
在上面的示例中,您将能够将函数的结果作为模式数组进行处理。
As per
George Jempty's
request to have the algorithm account for ties, I propose a modified version ofMatthew Flaschen's
algorithm.This will now return a string with the mode element(s) delimited by a
&
symbol. When the result is received it can be split on that&
element and you have your mode(s).Another option would be to return an array of mode element(s) like so:
In the above example you would then be able to handle the result of the function as an array of modes.
根据 Emissary 的 ES6+ 答案,您可以使用
Array.prototype.reduce
进行比较(而不是排序、弹出和可能改变数组),我对此进行了比较认为看起来相当光滑。我默认为 null,如果 null 是您正在过滤的可能选项,那么它并不总是会给您真实的响应,也许这可能是可选的第二个参数
与其他各种解决方案一样,缺点是它不不处理“绘制状态”,但这仍然可以通过稍微复杂的归约函数来实现。
Based on Emissary's ES6+ answer, you could use
Array.prototype.reduce
to do your comparison (as opposed to sorting, popping and potentially mutating your array), which I think looks quite slick.I'm defaulting to null, which won't always give you a truthful response if null is a possible option you're filtering for, maybe that could be an optional second argument
The downside, as with various other solutions, is that it doesn't handle 'draw states', but this could still be achieved with a slightly more involved reduce function.
由于我使用此函数作为面试官的测验,因此我发布了我的解决方案:
As I'm using this function as a quiz for the interviewers, I post my solution:
在这里尝试声明性方法。 该解决方案构建一个对象来统计每个单词的出现次数。 然后,通过将每个单词的总出现次数与对象中找到的最高值进行比较,将对象过滤为数组。
Trying out a declarative approach here. This solution builds an object to tally up the occurrences of each word. Then filters the object down to an array by comparing the total occurrences of each word to the highest value found in the object.
该解决方案的复杂度为
O(n)
:This solution has
O(n)
complexity:这是使用内置映射的现代版本(因此它不仅仅适用于可以转换为唯一字符串的事物):
Here’s the modern version using built-in maps (so it works on more than things that can be converted to unique strings):
为了真正易于阅读、可维护的代码,我分享这个:
希望它可以帮助某人;)!
For the sake of really easy to read, maintainable code I share this:
Hope it helps someone ;)!
是时候提出另一种解决方案了:
如果简洁性很重要(其实并不重要),那么:
如果要避免不存在的成员(例如稀疏数组),则需要额外的 hasOwnProperty 测试:
此处的其他答案将返回未定义。
Time for another solution:
If brevity matters (it doesn't), then:
If non–existent members are to be avoided (e.g. sparse array), an additional hasOwnProperty test is required:
Other answers here will return undefined.
这是另一种 ES6 方法,复杂度为 O(n)
Here is another ES6 way of doing it with O(n) complexity
另一个JS解决方案来自: https://www.w3resource.com /javascript-exercises/javascript-array-exercise-8.php
也可以尝试这个:
Another JS solution from: https://www.w3resource.com/javascript-exercises/javascript-array-exercise-8.php
Can try this too:
如果出现平局,此解决方案可以返回数组的多个元素。 例如,数组
有两个模式值:
3
和6
。这是解决方案。
This solution can return multiple elements of an array in case of a tie. For example, an array
has two mode values:
3
and6
.Here is the solution.
简单的解决方案!
循环所有元素并收集数组中每个元素的计数,这就是解决方案的想法
Easy solution !
Loop on all element and collect the Count of each element in the array that is the idea of the solution
这是我对这个问题的解决方案,但使用数字并使用新的“设置”功能。 它的性能不是很好,但我写这篇文章确实很有趣,而且它确实支持多个最大值。
顺便说一下,不要将其用于生产,这只是说明如何仅使用 ES6 和数组函数来解决它。
Here is my solution to this problem but with numbers and using the new 'Set' feature. Its not very performant but i definitely had a lot of fun writing this and it does support multiple maximum values.
By the way do not use this for production this is just an illustration of how you can solve it with ES6 and Array functions only.
也尝试一下,这不考虑浏览器版本。
Try it too, this does not take in account browser version.
使用 ES6,您可以像这样链接该方法:
如果两个元素出现相同的情况,它将返回这两个元素。 它适用于任何类型的元素。
With ES6, you can chain the method like this:
If two elements have the same occurrence, it will return both of them. And it works with any type of element.
我想出了一个更短的解决方案,但它使用的是 lodash。 适用于任何数据,而不仅仅是字符串。 对于对象可以使用:
这对于字符串:
只需根据特定条件对数据进行分组,然后找到最大的组。
I came up with a shorter solution, but it's using lodash. Works with any data, not just strings. For objects can be used:
This is for strings:
Just grouping data under a certain criteria, then finding the largest group.
这是我的方法,只需使用
.filter
即可。Here is my way to do it so just using
.filter
.这是我的解决方案:-
Here is my solution :-
这是我的解决方案:-
Here is my solution :-
在许多情况下,最好的性能可以提供
Map
(记住其中的计数):The best performance could give
Map
in many cases (remember counts in it):我猜你有两种方法。 两者各有优点。
排序然后计数或循环并使用哈希表为您进行计数。
哈希表很好,因为一旦完成处理,您还拥有所有不同的元素。 但是,如果您有数百万个项目,并且重复率较低,则哈希表最终可能会使用大量内存。 先排序再计数的方法将具有更可控的内存占用。
I guess you have two approaches. Both of which have advantages.
Sort then Count or Loop through and use a hash table to do the counting for you.
The hashtable is nice because once you are done processing you also have all the distinct elements. If you had millions of items though, the hash table could end up using a lot of memory if the duplication rate is low. The sort, then count approach would have a much more controllable memory footprint.
注:ct为数组长度。
Note: ct is the length of the array.