Найти подходящие предметы в цикле - PullRequest
0 голосов
/ 24 октября 2018

У меня есть цикл, который захватывает введенный пользователем номер (no_reps) и вставляет определенную информацию на основе этого.

Например, если пользователь вводит число 3, число от 1 до 3 будет вставлено вr.repetition_index.

Мне нужно сопоставить каждое из этих уникальных номеров для каждого цикла и вставить переменную treatment_indexes, чтобы для каждого r.repetition_index он не повторял одно и то же число.

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

|id|treatment_selection_id|repetition_index|treatment_index|
|1 |         1            |       1        |               |
|2 |         1            |       2        |               |
|3 |         1            |       3        |               |
|4 |         2            |       1        |               |
|5 |         2            |       2        |               |
|6 |         2            |       3        |               |
|7 |         3            |       1        |               |
|8 |         3            |       2        |               |
|9 |         3            |       3        |               |

Обратите внимание, что каждый treatment_selection_id имеет уникальный repetition_index, равный 1..3.Теперь для каждого repetition_index, равного 1, я хочу вставить уникальное число 1,3 в treatment_index и т. Д. С repetition_index 2 и 3.

Пока у меня есть следующее, но r.treatment_index не вставляет уникальный номер для каждого соответствия r.repetition_index.

no_reps = @trial.number_of_repetitions
@trial.treatment_selections.each do |r|
 r.repetitions.in_groups_of(no_reps).each_with_index do |a, i|
   treatment_indexes = (1..no_reps).to_a.shuffle
   a.each_with_index do |r, j|
     r.repetition_index = j + 1
     r.treatment_index = treatment_indexes[j]
   end
  end
end

1 Ответ

0 голосов
/ 24 октября 2018

Когда следующая группа повторяется, будет создан новый массив случайных чисел treatment_indexes, поэтому вы оставляете случайным образом порядок, в котором они распределены на уровне treatment_selecion_id.В ваших результатах вы должны увидеть, что treatment_selecion_id с одним и тем же номером будут иметь разные treatment_index.Но вы не смогли найти отношения уникальности между repetition_index и treatment_index.

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

Это изменение должно дать вамслучайность и устранение дубликатов на уровне repetition_index.

no_reps = @trial.number_of_repetitions
repet_treat = {} # you have to keep track of repetition_indexes and treatment_indexes
@trial.treatment_selections.each do |r|
 r.repetitions.in_groups_of(no_reps).each_with_index do |a, i|
   treatment_indexes = (1..no_reps).to_a # randomness will be handled elsewhere
   a.each_with_index do |r, j|
     r.repetition_index = j + 1
     # store treatment_index for this repetition_index in an array
     repeat_treat[r.repetition_index] ||= [] 
     # get the treatment_index you have already used for this repetition_index
     used_treat_indexes = repeat_treat[r.repetition_index]
     # delete the used indexes from the posibilities of the next and get a new random index
     r.treatment_index = (treatment_indexes - used_treat_indexes).sample
     # store your newely used treatment_index in its repetition_index group
     repeat_treat[r.repetition_index] << r.treatment_index
   end
  end
end

Структура @trial уже хранит treatment_index, поэтому вы должны иметь возможность реализовать ту же идею, используя @trial вместоновый хеш.

no_reps = @trial.number_of_repetitions
@trial.treatment_selections.each do |r|
 r.repetitions.in_groups_of(no_reps).each_with_index do |a, i|
   treatment_indexes = (1..no_reps).to_a # still handle randomness elsehwere
   a.each_with_index do |r, j|
     r.repetition_index = j + 1
     used_indexes = @trial
                      .treatment_selections
                      .map(&:repetitions)
                      .select { |rep| rep.repetition_index == r.repetition_index }
                      .map(&:treatment_index)
     r.treatment_index = (treatment_indexes - used_indexes).sample
   end
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...