2015-11-18 4 views
-1

У меня есть два сценария, которые ведут себя по-разному, один раз запускается один раз, в то время как другие дважды, не могут понять, почему может помочь любой PLZ?Объяснение кода ruby ​​для итерации по массиву хешей

СЦЕНАРИЙ - 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 

Может кто-нибудь, пожалуйста, объясните мне, почему это происходит, Что разница между двумя сценариями и их последующими выходами из-за которых строку коды? Я просто хочу извлечь class_id и section_id и выполнить некоторое вычисление, а затем перейти к следующей паре идентификаторов классов и секций и выполнить с ними одни и те же вычисления.

+1

Они оба работают дважды, это результат, который вас сбивает с толку. В первом примере вы печатаете один раз за ключ. Во втором примере вы производите все за ключ. hash.each будет перебирать все ключи данного хэша, в этом случае они имеют 2 клавиши, поэтому 2 раза. – lcguida

ответ

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 
1

Код блока внутри @newArray[@grades_counter].each будет работать 2 раза, потому что каждый хэш имеет 2 пары значения ключа.

И сокращенный вариант кода:

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

Есть лучше, чище, более «рубин, как» способы сделать это.

если grade_id и секции является то, что вы хотите, вы можете получить доступ к нему, как это:

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

Также обратите внимание, что когда вы перебирать хэша, она будет проходить столько раз, сколько есть ключи. Вот почему ваш текст выдается дважды.