My code has two main concerns
- it seems unecessairly long
- unable to use new each_with_object method without shadowing answer(variable)
How should I proceed to reduce my code and make my intention clearer?
require 'pp'
data = <<EOF
0 303567 3584 Write 0.000000
1 55590 3072 Write 0.000000
0 303574 3584 Write 0.026214
1 240840 3072 Write 0.026214
1 55596 3072 Read 0.078643
0 303581 3584 Write 0.117964
1 55596 3072 Write 0.117964
0 303588 3584 Write 0.530841
1 55596 3072 Write 0.530841
0 303595 3584 Write 0.550502
1 240840 3072 Write 0.550502
1 55602 3072 Read 0.602931
0 303602 3584 Write 0.648806
1 55602 3072 Write 0.648806
0 303609 3584 Write 0.910950
1 55602 3072 Write 0.910950
0 303616 3584 Write 0.930611
1 240840 3072 Write 0.930611
1 55608 3072 Read 0.983040
0 303623 3584 Write 1.028915
1 55608 3072 Write 1.028915
0 303630 3584 Write 1.330380
1 55608 3072 Write 1.33038
EOF
ary = Array.new
data.each_line { |line|
ary.push(line.split(" "))
}
answers = ary.map {|row| row[1]}
counts = Hash.new 0
answers.each do |answer|
counts[answer] += 1
end
# creates shadowing
# solution = answer.each_with_object(Hash.new(0)) { |answer,counts| counts[answer] += 1}
pp counts
1 Answer 1
Sorry, but I didn't get your question on the shadowing part... Anyway, if you want to shorten it (and try to use something similar to each_with_object), you can do it this way, as a oneliner :)
pp data.each_line.with_object(Hash.new(0)) {|row,solution| solution[row.split(" ")[1]]+=1}
Except for the indirect handling with the double square brackets, I think that it is quite readable :)
Explanation (slightly changed by introducing an "index" temp variable for the sake of clarity)
pp data
.each_line #cycling line by line
.with_object(Hash.new(0)) { |row,solution| #using a Hash as accumulator, later called solution
index=row.split(" ")[1] #setting the temp variable as the second column
solution[index]+=1 #increase the relevant counter in accumulator
}