【问题标题】:Adding elements of different arrays together将不同数组的元素加在一起
【发布时间】:2012-04-12 15:20:16
【问题描述】:

我正在尝试使用 CSV 计算三个数字的平均值并将其输出到单独的文件中。特别是,打开一个文件,取第一个值(名称),然后计算接下来三个值的平均值。对文件中的每个人多次执行此操作。

这是我的 Book1.csv

Tom,90,80,70
Adam,80,85,83
Mike,100,93,89
Dave,100,100,100
Rob,80,70,75
Nick,80,90,70
Justin,100,90,90
Jen,80,90,100

我正试图让它输出这个:

Tom,80
Adam,83
Mike,94
Dave,100
Rob,75
Nick,80
Justin,93
Jen,90

我将每个人都放在一个数组中,我可以让它与我编写的基本“伪”代码一起工作,但它不起作用。 到目前为止,这是我的代码:

#!/usr/bin/ruby
require 'csv'
names=[]
grades1=[]
grades2=[]
grades3=[]
average=[]
i = 0
CSV.foreach('Book1.csv') do |students|
  names << students.values_at(0)
  grades1 << reader.values_at(1)
  grades2 << reader.values_at(2)
  grades3 << reader.values_at(3)
end

while i<10 do
   average[i]= grades1[i] + grades2[i] + grades3[i]
   i= i + 1
end

CSV.open('Book2.csv', 'w') do |writer|
   rows.each { |record| writer << record }
end

while循环部分是我最关心的部分。有什么见解吗?

【问题讨论】:

  • CSV 文件的示例非常重要。
  • 这是很多额外的工作——似乎这一切都可以在一个循环中完成,而无需所有中间数组。

标签: ruby arrays csv


【解决方案1】:

如果你有一个要求和的值数组,你可以使用:

sum = array.inject(:+)

如果您将数据结构更改为:

grades = [ [], [], [] ]
...
grades[0] << reader.values_at(1)

那么你可以这样做:

0.upto(9) do |i|
  average[i] = (0..2).map{ |n| grades[n][i] }.inject(:+) / 3
end

有多种方法可以改进您的数据结构,以上是对您的代码影响最小的方法之一。

任何时候你发现自己在写作:

foo1 = ...
foo2 = ...

您应该将其识别为代码异味,并考虑如何将数据组织到更好的集合中。


这是我如何做到这一点的重写。请注意,它适用于任意数量的分数,而不是硬编码为 3:

require 'csv'
averages = CSV.parse(DATA.read).map do |row|
  name, *grades = *row
  [ name, grades.map(&:to_i).inject(:+) / grades.length ]
end
puts averages.map(&:to_csv)
#=> Tom,80
#=> Adam,82
#=> Mike,94
#=> Dave,100
#=> Rob,75
#=> Nick,80
#=> Justin,93
#=> Jen,90

__END__
Tom,90,80,70
Adam,80,85,83
Mike,100,93,89
Dave,100,100,100
Rob,80,70,75
Nick,80,90,70
Justin,100,90,90
Jen,80,90,100

【讨论】:

  • 我已经编辑了我的答案以使用您的数据,并创建最接近的整数平均值(而不是使用浮点除法),因为这就是您所说的。
  • 我的问题是如何实现它来访问 Book1.csv?
  • 参见the docs for CSV,了解如何从文件创建数组(提示:参见read)。但总的来说,我的回答中重要的是如何将一行成绩转换为平均数的一行;有很多方法可以使用它来将一个完整的文件转换成另一个。
猜你喜欢
  • 1970-01-01
  • 2021-04-27
  • 1970-01-01
  • 2020-01-27
  • 1970-01-01
  • 2013-05-28
  • 1970-01-01
  • 2016-09-25
  • 2019-01-03
相关资源
最近更新 更多