Как посчитать количество появлений определенного значения в хэше Ruby?

У меня есть хэш Ruby (изначально был param в рельсах)

Как я могу посчитать количество correctness в каждом answers_attributes?

(Почему я делал это, я пытаюсь создать тест с несколькими вариантами ответов по рельсам. На один вопрос может быть много ответов. Я пытался использовать multi_correct флажок, чтобы решить, какой вопрос имеет много правильных ответов. Но это как-то нелогично. Поэтому я хочу, чтобы бэкэнд решил, посчитав количество правильностей в каждом вопросе)

{
  "utf8" => "✓", "authenticity_token" => "r5xX46JG/GPF6+drEWmMPR+LpOI0jE0Tta/ABQ0rZJJE+UbbEjvNMLP6y2Z9IsWlXq27PR6Odx0EK4NECPjmzQ==", "question_bank" => {
    "name" => "123213", "questions_attributes" => {
      "0" => {
        "content" => "question 1", "multi_correct" => "no", "answers_attributes" => {
          "0" => {
            "content" => "as1", "correctness" => "false"
          }, "1" => {
            "content" => "as2", "correctness" => "false"
          }, "2" => {
            "content" => "as3", "correctness" => "true"
          }, "3" => {
            "content" => "as4", "correctness" => "false"
          }
        }
      }, "1" => {
        "content" => "q2", "multi_correct" => "no", "answers_attributes" => {
          "0" => {
            "content" => "a1", "correctness" => "false"
          }, "1" => {
            "content" => "a2", "correctness" => "false"
          }, "2" => {
            "content" => "a3", "correctness" => "true"
          }, "3" => {
            "content" => "a4", "correctness" => "false"
          }
        }
      }, "2" => {
        "content" => "q3", "multi_correct" => "no", "answers_attributes" => {
          "0" => {
            "content" => "aa1", "correctness" => "false"
          }, "1" => {
            "content" => "aa2", "correctness" => "false"
          }, "2" => {
            "content" => "aa3", "correctness" => "false"
          }, "3" => {
            "content" => "aa4", "correctness" => "true"
          }
        }
      }
    }
  }, "commit" => "Submit"
}

2 ответа

Решение

Я интерпретировал это как поиск количества правильных ответов на каждый вопрос. Если это так, вы можете достичь этого с помощью следующего:

your_hash['question_bank']['questions_attributes'].values.reduce(Hash.new(0)) do |hash, question| 
  question['answers_attributes'].each do |_k, answer| 
    hash[question['content']] += 1 if answer['correctness'] == 'true'
  end
  hash
end

Это дает результат:

# => {"question 1"=>1, "q2"=>1, "q3"=>1}

По сути, код выполняет следующие действия:

  • перебирает вопросы, используя reduce сделать хеш со значением по умолчанию 0 имеется в наличии
  • перебирает ответы на этот вопрос и добавляет 1 к сопровождающему hash[question_name] (или же hash[question['content']] в примере) когда ответ правильный
  • возвращает сопровождающий хеш

Если вы используете Rails, на которую, возможно, намекает ссылка на параметры, подумайте об использовании each_with_object скорее, чем reduce; таким образом, вы можете избежать отставания hash в примере как всегда возвращает аккумулятор.

Надеюсь, это поможет - дайте мне знать, если у вас есть какие-либо вопросы.

Если вы просто хотите посчитать, сколько правильных ответов в хэше, вы можете использовать inject сделать это. Вот способ:

# iterate over the questions
hash['question_bank']['questions_attributes'].values.inject(0) do |count, q|
  # iterate over the answers
  count += q['answers_attributes'].values.inject(0) do |a_count, a|
    a_count += a['correctness'] == 'true' ? 1 : 0
  end
end
Другие вопросы по тегам