加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

数组 – Ruby数组按2种不同方式排序

发布时间:2020-12-17 03:29:39 所属栏目:百科 来源:网络整理
导读:我有一个对象数组,我试图按多个标准排序.大多数比较只是做 =在哈希上,所以使用sort_by非常快,但其中一个更复杂. 这个阵列是足球队的,目前它的排序方式如下: teams.sort_by { |item| [item.points,item.goal_dif,item.goals] } 但是,如果最后2支球队在这3个
我有一个对象数组,我试图按多个标准排序.大多数比较只是做< =>在哈希上,所以使用sort_by非常快,但其中一个更复杂.

这个阵列是足球队的,目前它的排序方式如下:

teams.sort_by { |item| [item.points,item.goal_dif,item.goals] }

但是,如果最后2支球队在这3个领域拥有相同的值,我希望决胜局是我所做的一个功能,a_beat_b(teamA,teamB).

我尝试使用Array.sort,但与sort_by相比,前几个人的速度非常慢……我的实现是这样的:

teams.sort(| a,b | [a.points,a.goals_dif,a.goals]< => [b.points,b.goals_dif,b.goals])
与sort_by相比,它非常慢. points,goals_dif和目标的函数需要一些简单的查询,但如果它必须做数百个就会陷入困境.

我不擅长Ruby,所以不知道把我的a_beats_b放在哪里. (如果A击败,则返回1,0或-1,对B进行抽取或丢失,具有代表性)

解决方法

I tried using Array.sort,but it’s extremely slow compared to sort_by for those first few

这是因为sort多次调用给定的块.这是一个示例,以显示引擎盖下发生的事情:(按长度排序“苹果”,“梨”和“无花果”)

def length(str)
  puts "calculating #{str.inspect}.length"
  str.length
end

array = %w{apple pear fig}
array.sort { |a,b| length(a) <=> length(b) }
#=> ["fig","pear","apple"]

我们的长度方法输出:

calculating "apple".length
calculating "pear".length
calculating "apple".length
calculating "fig".length
calculating "pear".length
calculating "fig".length

如您所见,在排序期间会多次调用length.想象一下,这些是数据库查询.

另一方面,sort_by为每个元素调用一次块,构建一个内部映射:

array.sort_by { |a| length(a) }
#=> ["fig","apple"]

输出:

calculating "apple".length
calculating "pear".length
calculating "fig".length

对于昂贵的操作(如数据库查询),这要快得多.但它也不太灵活 – 你不能动态比较a和b了.

但是,您可以存储(昂贵的)操作的结果,例如使用哈希:(这称为memoization)

hash = Hash.new { |h,k| h[k] = length(k) }

并在sort中使用hash:

array.sort { |a,b| hash[a] <=> hash[b] }
# calculating "apple".length
# calculating "pear".length
# calculating "fig".length
#=> ["fig","apple"]

排序后,我们的哈希看起来像这样:

hash #=> {"apple"=>5,"pear"=>4,"fig"=>3}

应用于您的代码,这样的东西应该工作:

hash = Hash.new { |h,k| h[k] = [k.points,k.goal_dif,k.goals] }
teams.sort { |a,b| hash[a] == hash[b] ? a_beats_b(a,b) : hash[a] <=> hash[b] }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读