2

可以说我有这样的文本文件:

1 2 3
4 5 6
7 8 9
...

我想将它读入这样的数据结构:

h[1] = { "a" => 1, "b" => 2, "c" => 3 }
h[2] = { "a" => 4, "b" => 5, "c" => 6 }
h[3] = { "a" => 7, "b" => 8, "c" => 9 }

起初这似乎很容易。我用:

 lines=File.read(ARGV[0]).split("\n")
 h=[]
 lines.each ( |x| h << x.split())

并且完全卡在了这一点上。如何将 h 转换为哈希数组?

4

5 回答 5

4
def parse(filename)
  File.readlines(filename).map do |line|
    Hash[('a'..'c').zip(line.split.map(&:to_i))]
  end
end

parse(ARGV[0]) # => [{"a"=>1, "b"=>2, "c"=>3}, {"a"=>4, "b"=>5, "c"=>6}, {"a"=>7, "b"=>8, "c"=>9}] 
于 2013-05-08T23:32:21.427 回答
4
lines = File.readlines(ARGV[0])
lines.map { |l| x = l.split(/\s/).map(&:to_i); { 'a' => x[0], 'b' => x[1], 'c' => x[2] } }
于 2013-05-08T23:10:05.400 回答
1

有一个宝石可以用于此:smarter_csv

把它放在你的 Gemfile 中:

 gem 'smarter_csv',  '1.0.5'

接着:

 require 'smarter_csv'
 result = SmarterCSV.process('/tmp/bla.csv', 
         {:col_sep => ' ', 
          :headers_in_file => false, 
          :user_provided_headers => ['a','b','c'],
          :strings_as_keys => true
         }
 )
  => [{"a"=>1, "b"=>2, "c"=>3}, 
      {"a"=>4, "b"=>5, "c"=>6}, 
      {"a"=>7, "b"=>8, "c"=>9}] 

 result[0]
  => {"a"=>1, "b"=>2, "c"=>3}

另请参阅:smarter_csv自述文件

于 2013-05-08T23:29:51.530 回答
1

我会使用:

require 'pp'

ary = []
DATA.each_line do |li|
  ary << Hash[%w[a b c].zip(li.split)]
end

pp ary

__END__
1 2 3
4 5 6
7 8 9

运行我得到:

[{"a"=>"1", "b"=>"2", "c"=>"3"},
 {"a"=>"4", "b"=>"5", "c"=>"6"},
 {"a"=>"7", "b"=>"8", "c"=>"9"}]

如果您希望它成为您的变量名,请更改ary为。h

如果您正在从文件中读取,请使用File.foreach('file/to/read.txt')而不是each_line.

于 2013-05-08T23:37:28.637 回答
0

我的解决方案不如 Christian 的优雅:

base = ['a','b','c']
h=[]
i = 0 # traverses the a,b,c
j = 1 # traverses the lines of the hash h

File.open(ARGV[0]).each_line do |line|
  arr = line.split(' ')
  arr.each do |x|
    if !h[j].nil?
      h[j][base[i]] = x.to_i
    else # first entry in the hash should be set like this:
      h[j] = {base[i] => x.to_i}
    end
    i += 1;
  end
  i = 0
  j += 1
end
p h[1]
p h[2]
p h[3]

输出:

{"a"=>"1", "b"=>"2", "c"=>"3"}
{"a"=>"4", "b"=>"5", "c"=>"6"}
{"a"=>"7", "b"=>"8", "c"=>"9"}

我从 j = 1 开始,因为这是 OP 要求的,即使从零开始可能更有意义。

于 2013-05-08T23:28:31.307 回答