1

I have to create 28 arrays named the following:

all_questions_1 = []
all_questions_2 = []
...
all_questions_28 = []

I do not want to create them manually so I am trying to figure out how to do so dynamically with a lot of failed attempts.

I checked the previous questions with little success.

Ruby dynamically naming arrays

Ruby dynamic variable name

After reading the comment I added this additional explanation on the why I asked this question

What I am trying to solve is a problem I have inside a Ruby_on_Rails controller for an custom action called replies

The action is the following:

def replies
    @project = Project.find(params[:project_id])
    @paper = Paper.find(params[:paper_id])
    @replies = Question.where("project_id = ? AND paper_id = ?", params[:project_id], params[:paper_id])
end

@replies gives back a long object containing all the replies on each paper contained in a project. Therefore, one paper can be answered by multiple users. Each paper is inside a project. Each project contains several papers. (The user can answer all the 28 questions with: NA, NO, MAYBE, YES which I translated to "-1", "0", "0.5", "1")

This is what the object @replies gives me back. enter image description here

Now, once I have that. I have to map all the 28 replies/questions. I want to do the following.

@replies.map do |reply|
  all_question_1 << reply.question_1.to_i
end

And I want to do it 28 times (there are 28 questions), that is why I need 28 arrays. I am doing it because I want the possible answers which are strings "-1", "0", "0.5", "1" to be changed into numbers -1, 0, 0,5, 1

Once dode that, I want to count for each question (all_question_1, all_question_2... all_question_28) how many questions with -1 or 0 or 0.5 or 1 are contained.

TO SUM UP:

I need to build the following code 28 times changing the name_of_array_[NUMBER] from 1 to 28:

all_question_1 = []

@replies.map do |reply|
  all_question_1 << reply.question_1.to_i
end

na_question_1 = all_question_1.count(-1)
no_question_1 = all_question_1.count(0)
maybe_question_1 = all_question_1.count(0.5)
yes_question_1 = all_question_1.count(1)

len_question_1 = all_question_1.length

I do not want to do it manually, so I was wondering if there is a way to dynamically change the _NUMBER from 1 to 28.

3
  • Why doesn't that first link help? It seems to be doing exactly what you want Commented Feb 4, 2019 at 21:38
  • 1
    For right answer, can you provide example of how you are going to consume those arrays. Because there is a possibility that you don't need those names at all Commented Feb 4, 2019 at 22:09
  • I added the information you requires. Many thanks! Commented Feb 4, 2019 at 23:15

3 Answers 3

1

Using dynamic variables is something I have never ever found a need for. You should find another data structure to store them (for example, an array of arrays).

For example,

all_questions_arrays = 28.times.map { |i| [i] }

print all_questions_arrays[20]
# => [20]
Sign up to request clarification or add additional context in comments.

2 Comments

Many thanks. I had to add more information on the why I need 28 array, therefore I change my question.
@FBSO you should give up on the idea of dynamic variable names. There is no reason to do this, instead of using some sort of proper dynamic indexing (hashes or arrays)
1

You can create dynamically 28 instance variables like this:

1.upto(28){ |i| instance_variable_set("@all_questions_#{i}", [])}

Access to one of 28 variables through @ sign. Ex. @all_questions_3

1 Comment

Thanks for your answer. I changed my question a bit, but indeed your reply was helpful.
0

As per the first link you have in your question I think that is the best way to do it and would look something like this.

hash = Hash.new
28.times do |counter|
  hash[:"all_questions_#{counter + 1}"] = @replies.pluck(:"question_#{counter + 1}").map(&:to_i)
end

You'd end up with a hash whose keys match with the naming convention you want and the values be the arrays filled with the the question values from each of the @replies. When you want to get a specific array from the hash you can do

 hash[:all_questions_1] # returns [1, -1, 0, ....]

3 Comments

I get the following error message: undefined method []=' for 854007252925858582:Integer (NoMethodError) Did you mean? []´
@FBSO I updated my answer. That should work. You weren't declaring your hash.
@FBSO I updated my answer again. I recommend using .pluck you can get all the answers from each of the replies for each question. I think my answer should get you exactly what you want.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.