gpt4 book ai didi

ruby - 以 nil 为键对散列进行排序

转载 作者:数据小太阳 更新时间:2023-10-29 08:19:00 27 4
gpt4 key购买 nike

我正在学习本教程:http://tutorials.jumpstartlab.com/projects/jsattend.html

在第 7 次迭代中,第 3 步我们对哈希进行排序,称为 state_data,它以 nil 作为键。建议的解决方案是:

state_data = state_data.sort_by{|state, counter| state unless state.nil?}

不幸的是,这不适用于 ruby​​ 1.9.2p290(2011-07-09 修订版 32553)[x86_64-darwin11.0.0]。例如:

~% irb
>> things = { nil => "a", 2 => "b", 3 => "c" }
>> things.sort_by { |k, v| k unless k.nil? }
ArgumentError: comparison of NilClass with 2 failed
from (irb):6:in `sort_by'
from (irb):6
from /Users/jacopo/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'

等价物也是如此:

>> things.sort_by { |k, v| k if k }
ArgumentError: comparison of NilClass with 2 failed
from (irb):3:in `sort_by'
from (irb):3
from /Users/jacopo/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'

在本教程的案例中,由于它是按州两个字母代码排序的,因此可能的解决方案是:

state_data = state_data.sort_by{|state, counter| state.nil? ? "ZZ" : state }

这显然是一个 hack。

处理这个问题的 Ruby 方法是什么?

最佳答案

线

state_data.sort_by { |state, counter| state unless state.nil? }

实际上等同于一个简单的state_data.sort,因为(state unless state.nil?) == state 在任何情况下。您可以做的是将正确的键与 nil 键分开,并且只对前者进行排序:

state_data.select(&:first).sort + state_data.reject(&:first)

在更一般的情况下,您还可以像这样定义自定义比较函数:

def compare(a, b)
return a.object_id <=> b.object_id unless a || b
return -1 unless b
return 1 unless a
a <=> b
end

state_data.sort { |a, b| compare(a.first, b.first) }

快速查看一下,您会发现它非常丑陋。事实上,您应该重新考虑您在这里选择的数据结构。 nil 键对我来说似乎不太明智。

更新:通过查看您链接到的教程,我认为其中有很多次优信息。看看下面的一段“Ruby”,例如:

ranks = state_data.sort_by{|state, counter| counter}.collect{|state, counter| state}.reverse
state_data = state_data.sort_by{|state, counter| state}

state_data.each do |state, counter|
puts "#{state}:\t#{counter}\t(#{ranks.index(state) + 1})"
end

你可以把它写得更干净并得到相同的结果:

rank = state_data.sort_by(&:last)
state_data.sort.each do |data|
puts "%s:\t%d\t(%d)" % [*data, rank.index(data) + 1]
end

作者还推荐了这样的代码

filename = "output/thanks_#{lastname}_#{firstname}.html"
output = File.new(filename, "w")
output.write(custom_letter)

虽然 Ruby 惯用法是:

filename = "output/thanks_#{lastname}_#{firstname}.html"
File.open(filename, 'w') { |f| f.write(custom_letter) }

这说明作者似乎不太擅长Ruby。因此,我不能推荐该教程。

关于ruby - 以 nil 为键对散列进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8954278/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com