Ruby数组:在链接方法时获取所有具有最大值的元素(即,没有排序数组的句柄)
Posted
技术标签:
【中文标题】Ruby数组:在链接方法时获取所有具有最大值的元素(即,没有排序数组的句柄)【英文标题】:Ruby array: getting all the elements that have the max value while chaining methods (namely, without having a handle on the sorted array) 【发布时间】:2021-12-26 16:08:03 【问题描述】:假设你需要获取一个数组中所有具有最大值的元素。
一种可能的方法是sort
数组然后使用Enumerable#take_while
:
array = [ 1, 3, 2, 3, 2, 3 ].sort |a,b| b - a
array.take_while |e| e == array[0]
#=> [3, 3, 3]
现在,当您漂亮地链接方法并且不想仅仅为了存储排序数组而停止链(您需要它来引用它的第一个take_while
块中的元素),你会怎么做?
我在下面发布了问题和答案以供参考,但我可能错过了更好的方法,所以请随意发布您自己的方法
【问题讨论】:
也许改写“所有最好的元素”?没有评价标准,“最好”就没有任何意义。 可能类似于“所有具有最大值的元素”? @SergioTulentsev,感谢您的建议;我修好了 Fravadona 和 @engineersmnky,关于我现在删除的答案:哎呀。 【参考方案1】:另一种方式:
arr = [ 1, 3, 2, 3, 2, 3 ]
arr.sort |a,b| b - a.tap |a| a.select! |e| e == a.first
#=> [3, 3, 3]
请注意,arr
不会发生变异。
【讨论】:
array.group_by(&:itself).max.last
是另一种选择。和array.tally
不一样,但可能就足够了。
@Fravadona 说了什么。由于局部变量mx
的作用域,它不会保留其值,因此每次都会重新定义。示例replit.com/@engineersmnky/…
请注意,以上所有评论均引用了我的原始答案,这是不正确的,或者至少效率很低。
这次为什么用sort
?在执行select!
之前是否有可能获得max
?
@Fravadona,我不想改变 arr
和 arr.dup.tap |a| mx = a.max; a.select! |e| e == mx
似乎不符合问题的精神。建议?【参考方案2】:
红宝石
我对这个问题的原始回答:sort
.slice_when
.first
[ 1, 3, 2, 3, 2, 3 ].sort |a,b| b - a.slice_when |a,b| b != a.first
#=> [3, 3, 3]
[ 1, 3, 2, 3, 2, 3 ].sort |a,b| b - a.slice_when |a,b| b != a.first
#=> [3, 3, 3]
注意:由于slice_when
返回一个Enumerator
,当与first
链接时,此解决方案不会遍历所有已排序的数组。在tough下面有一个性能更高的解决方案。
红宝石 >= 2.5
结合 @engineersmnky 和 @Cary 方法:then
和 max
+select
[ 1, 3, 2, 3, 2, 3 ].then |arr| mx = arr.max; arr.select |elm| elm == mx
#=> [3, 3, 3]
【讨论】:
Ruby 2.5 添加了yield_self
并且 ruby 2.6 将其别名为 then
因此您的原始代码可以更改为 array.sort.reverse.then |a| a.take_while |e| e == a[0]
【参考方案3】:
你可以试试这个
pry(main)> [ 1, 2, 2, 3, 3, 3 ].sort.slice_when |a,b| b > a.to_a.last
=> [3, 3, 3]
与上一个解决方案有点相似,但也有所不同。
来源https://ruby-doc.org/core-3.0.2/Enumerable.html#method-i-slice_when
【讨论】:
在这个版本中,slice_when
将遍历整个数组,这是次优的。以上是关于Ruby数组:在链接方法时获取所有具有最大值的元素(即,没有排序数组的句柄)的主要内容,如果未能解决你的问题,请参考以下文章