用于迭代哈希数组的ruby代码的说明

时间:2015-11-18 08:05:46

标签: ruby-on-rails arrays ruby loops hash

我有两个脚本的行为不同,一次运行一次而另一次运行两次,无法理解为什么任何一个PLZ都能帮助?

SCRIPT - 1

@newArray=[{grade_id:"1",sections:"4"},
           {grade_id:"2",sections:"8"},
           {grade_id:"3",sections:"7"},
           {grade_id:"4",sections:"7"},
           {grade_id:"5",sections:"3"},
           {grade_id:"6",sections:"3"},
           {grade_id:"7",sections:"3"}]

@total_grades_passed = @newArray.count
@grades_counter = 0

while @grades_counter < @total_grades_passed do
  @newArray[@grades_counter].each do |key, value|
     print [key]
     puts [value] 
  end
  @grades_counter += 1
end

给出以下输出。

[:grade_id]1
[:sections]4
[:grade_id]2
[:sections]8
[:grade_id]3
[:sections]7
[:grade_id]4
[:sections]7
[:grade_id]5
[:sections]3
[:grade_id]6
[:sections]3
[:grade_id]7
[:sections]3

虽然SCRIPT - 2提供完全不同的输出。

@newArray=[{grade_id:"1",sections:"4"},
           {grade_id:"2",sections:"8"},
           {grade_id:"3",sections:"7"},
           {grade_id:"4",sections:"7"},
           {grade_id:"5",sections:"3"},
           {grade_id:"6",sections:"3"},
           {grade_id:"7",sections:"3"}]

@total_grades_passed = @newArray.count
@grades_counter = 0  

while @grades_counter < @total_grades_passed do
  @newArray[@grades_counter].each do |x,y|
    @grade_id = @newArray[@grades_counter][:grade_id].to_i
    @no_of_sections = @newArray[@grades_counter][:sections].to_i
    puts "Grade id is #{@grade_id} and its class is #{@grade_id.class}"
    puts "section is #{@no_of_sections} and its class is #{@no_of_sections.class}"
  end
  @grades_counter += 1
end

给出以下奇怪的输出。

Grade id is 1 and its class is Fixnum
section is 4 and its class is Fixnum
Grade id is 1 and its class is Fixnum
section is 4 and its class is Fixnum
Grade id is 2 and its class is Fixnum
section is 8 and its class is Fixnum
Grade id is 2 and its class is Fixnum
section is 8 and its class is Fixnum
Grade id is 3 and its class is Fixnum
section is 7 and its class is Fixnum
Grade id is 3 and its class is Fixnum
section is 7 and its class is Fixnum
Grade id is 4 and its class is Fixnum
section is 7 and its class is Fixnum
Grade id is 4 and its class is Fixnum
section is 7 and its class is Fixnum
Grade id is 5 and its class is Fixnum
section is 3 and its class is Fixnum
Grade id is 5 and its class is Fixnum
section is 3 and its class is Fixnum
Grade id is 6 and its class is Fixnum
section is 3 and its class is Fixnum
Grade id is 6 and its class is Fixnum
section is 3 and its class is Fixnum
Grade id is 7 and its class is Fixnum
section is 3 and its class is Fixnum
Grade id is 7 and its class is Fixnum
section is 3 and its class is Fixnum

任何人都可以解释一下为什么会发生这种情况,两个脚本之间的区别及其后续输出是由于哪些代码行? 我只想提取grade_id和section_id并进行一些计算,然后转到下一对等级和部分ID,并对它们进行相同的计算。

3 个答案:

答案 0 :(得分:3)

有更好,更清洁,更“红宝石般”的方法来做到这一点。

如果grade_id和sections是您想要的,您可以像这样访问它:

@newArray.each do |hash|
  hash.each do |grade_id, sections|
    # do something
  end
end

另请注意,当您遍历哈希时,它将传递与密钥一样多的次数。这就是你的文字输出两次的原因。

答案 1 :(得分:1)

@newArray[@grades_counter].each内的阻止代码将运行2次,因为每个哈希都有2对键值。

代码的较短版本:

@newArray.each do |hash|
  hash.each do |key, value|
    print [key]
    puts [value]
  end
end

答案 2 :(得分:1)

在第二个示例中,您不想迭代Hash。您正在迭代哈希键(即使您不使用它)。

你应该这样做:

@newArray=[{grade_id:"1",sections:"4"},{grade_id:"2",sections:"8"},
            {grade_id:"3",sections:"7"},{grade_id:"4",sections:"7"},
            {grade_id:"5",sections:"3"},{grade_id:"6",sections:"3"},
            {grade_id:"7",sections:"3"}]

@total_grades_passed = @newArray.count
@grades_counter = 0  

while @grades_counter < @total_grades_passed do

    @grade_id = @newArray[@grades_counter][:grade_id].to_i
    @no_of_sections = @newArray[@grades_counter][:sections].to_i
    puts "Grade id is #{@grade_id} and its class is #{@grade_id.class}"
    puts "section is #{@no_of_sections} and its class is #{@no_of_sections.class}"

  @grades_counter += 1
end