5

所以我没有太多Ruby知识,但需要编写一个简单的脚本。我将尝试详细解释我的困境,但如果您仍需要澄清,请告诉我。

我的脚本每组包含 3 个数字。比方说,例如,我们有每个人的这三条信息:Age, Size, and Score。所以,我需要有一种方法来评估一个人是否存在一定的年龄和体型。如果是这样,那么我想输出那个人的分数。

我知道跟踪此信息的唯一方法是创建3 separate arrays,每个都包含一个information. 我可以检查年龄是否包含在一个数组中,如果是,我可以找到它的索引(每个类别中的每个值都是唯一的——因此不会重复“年龄”、“大小”或“分数”)。然后我可以检查大小数组中相同索引处的值是否与指定大小匹配。如果是这样,我可以输出在同一索引处的第三个数组中找到的分数。我宁愿不这样做,而是将每个人的年龄体型分数保持在一起。

所以,我在这样的数组中尝试了数组:

testarray = [
  [27, 8, 92],
  [52, 12, 84]
]

但是,问题在于我不确定如何访问这些子数组中的值。所以我知道我可以使用类似 testarray.include?(27) 的东西来检查主数组中是否存在 27,但是我将如何检查 27 和 8 是否是 testarray 子数组中的前两个值,如果是,然后输出 的第三个值subarray,92。

然后我尝试了一个哈希数组,如下所示:

testarrayb = [
{ :age => 27, :size => 8, :score => 92 },
{ :age => 52, :size => 12, :score => 84 }
]

我知道我可以testarrayb[0][:score]用来获取 92,但我如何首先检查数组是否包含一个同时具有指定年龄和大小的哈希,如果是,则输出该哈希的分数?类似于testarrayb[:age].include?(value)检查每个哈希的年龄,然后检查相同哈希的大小。如果两者都匹配指定值,则输出该哈希的分数。

如果有人能指出我正确的方向,我将不胜感激。如果您建议这样做,请随意展示一种更有效且完全不同的技术。谢谢你的时间!

4

6 回答 6

3

为什么不创建一个简单的类来表示您的数据,例如使用Struct. 然后提供一些类方法来处理过滤。

Entry = Struct.new(:age, :size, :score) do
  # Holds the data (example)
  def self.entries; @entries ||= [] end

  # Example filtering method
  def self.score_by_age_and_size(age, size)
    entry = entries.find { |e| e.age == age && e.size == size }
    entry.score if entry
  end
end

# Add some entries
Entry.entries << Entry.new(27, 8, 92)
Entry.entries << Entry.new(52, 13, 90)

# Get score
Entry.score_by_age_and_size(27, 8) # => 92
Entry.score_by_age_and_size(27, 34) # => nil
于 2013-04-15T16:28:41.570 回答
2

这将返回一个满足条件的哈希数组,然后在返回的哈希数组中分配第一个哈希的分数。

# return an array of hashes that satisfy the conditions
array_of_hashes = testarrayb.select { |h| h[:age] == 27 && h[:size] == 8 }

# assign the score
score = array_of_hashes[0][:score]

编辑:你可能想把它放在一个方法中

# use an instance variable to reference the initial array defined outside this method
@testarrayb = [{:age=>27, :size=>8, :score=>92}, {:age=>52, :size=>12, :score=>84}]

def find_person(age, size)
  array_of_hashes = @testarrayb.select { |h| h[:age] == age && h[:size] == size }

  # since values in each column are unique we can assume array size of 0 or 1
  # return false if not found otherwise return the score
  !array_of_hashes.empty? && array_of_hashes[0][:score]
end

并这样称呼它:

find_person 27, 8
# => 92 

find_person 27, 7
# => false
于 2013-04-15T15:14:55.677 回答
1

从您的要求中我可以看出(“我需要有一种方法来评估一个人是否存在具有特定年龄和大小”“我如何首先检查数组是否包含具有指定年龄和大小的哈希" ),您总是通过他们的年龄和大小对来识别一个人,并且您希望基于该对作为键来引用他们的分数。由于 Ruby 允许任何类型的 Object 作为 Hashes 中的键(或值),我们可以直接翻译:

# `scores` hash is structured { [age, size] => score, ... }
scores = {[27, 8] => 92, [52, 12] => 84}

您可以询问是否存在具有特定年龄和尺寸对的人:

scores.include?([27, 8])  # => true
scores.include?([27, 7])  # => false
scores.include?([28, 8])  # => false
scores.include?([52, 12]) # => true

您可以为一个人分配一个新分数(同样,由年龄/大小对标识):

scores[[52, 12]] = 97
scores                    # => {[27, 8]=>92, [52, 12]=>97}

或者当然,因为你想访问这个值,你总是可以在nil之后进行测试:

score = scores[[27, 8]]   # `score` is now `92`
if !score.nil?
  # Do something with `score`
end

我更喜欢使用 Array 来表示一对,但另一种选择是使用 Hash,以便您可以为清楚起见命名元素而不必担心顺序:

scores = {{:age => 27, :size => 8} => 92, {:age => 52, :size => 12} => 84}
scores[{:size => 8, :age => 27}] # => 92
于 2013-04-15T16:48:47.037 回答
1

哈希的哈希值会为您解决问题吗?

testhash = {27 => {8 => 92}, 52 => {12 => 84}}
p testhash             # {27=>{8=>92}, 52=>{12=>84}}
p testhash[27][8]      # 92
p testhash[27][42]     # nil
testhash[27][42] = 99
p testhash             # {27=>{8=>92, 42=>99}, 52=>{12=>84}}
p testhash[27][42]     # 99

只要年龄/尺寸对是唯一的,这应该是非常有效的。

于 2013-04-15T15:09:02.703 回答
0
def person_score (*input)
    testarray = [
    [27, 8, 92],
    [52, 12, 84]
    ]
        testarray.each_with_object("") do|i,mem| 
            h = Hash[*([:age,:size,:score].zip(i).flatten)]
            (h.values.first(2) == input) ? (return h[:score]) : ( mem.replace("age and size not matched"))
        end
end

p person_score(27,12)  #=> "age and size not matched" 
p person_score(27,8)   #=> 92
p person_score(52,44)  #=> "age and size not matched"
p person_score(52,12)  #=> 84
于 2013-04-15T14:04:48.657 回答
0

你可能会做这样的事情:

[
  { age: 27, size: 8,  score: 92 },
  { age: 52, size: 12, score: 84 }
].map { |e| e[:age] == 27 && e[:size] == 8 ? e[:score] : nil }.compact

map将返回一个array带有块结果的新的(e[:score]如果条件匹配或nil不匹配,它将为您提供。compact然后将删除结果中不需要nilarray.

然而,这种行为听起来很适合它自己的类,因为我刚刚展示的内容包含很多硬编码的东西(尤其是选择条目的条件),这很糟糕。也许尝试为此找出一个不错的课程?

于 2013-04-15T13:31:25.503 回答