2014-04-17 59 views
2

我希望能夠將文件讀取到關聯數組中,我可以通過列頭名稱訪問元素。將文件讀入關聯數組

我的文件的格式如下:

 
KeyName Val1Name Val2Name ... ValMName 
Key1  Val1-1  Val2-1 ... ValM-1 
Key2  Val1-2  Val2-2 ... ValM-2 
Key3  Val1-3  Val2-3 ... ValM-3 
..   ..   ..  .. .. 
KeyN  Val1-N  Val2-N ... ValM-N 

唯一的問題是我沒有線索如何做到這一點做。到目前爲止,我有:

scores = File.read("scores.txt") 
lines = scores.split("\n") 
lines.each { |x| 
    y = x.to_s.split(' ') 
} 

哪些接近我想要的,但仍然無法使它成爲可用於我的格式。

+0

是由製表符或一定數量的空格分隔的列? – bjhaid

+0

他們看起來像只是無限數量的空間。絕對不是標籤。 – Brianne

回答

0

可在3線來完成(這就是爲什麼我喜歡紅寶石)

scores = File.readlines('/scripts/test.txt').map{|l| l.split(/\s+/)} 
headers = scores.shift 
scores.map!{|score|Hash[headers.zip(score)]} 

現在scores包含您的散列陣列

這裏是一個詳細的解釋

#open the file and read 
#then split on new line 
#then create an array of each line by splitting on space and stripping additional whitespace 
scores = File.open('scores.txt', &:read).split("\n").map{|l| l.split(" ").map(&:strip)} 
#shift the array to capture the header row 
headers = scores.shift 
#initialize an Array to hold the score hashs 
scores_hash_array = [] 
#loop through each line 
scores.each do |score| 
    #map the header value based on index with the line value 
    scores_hash_array << Hash[score.map.with_index{|l,i| [headers[i],l]}] 
end 
#=>[{"KeyName"=>"Key1", "Val1Name"=>"Val1-1", "Val2Name"=>"Val2-1", "..."=>"...", "ValMName"=>"ValM-1"}, 
    {"KeyName"=>"Key2", "Val1Name"=>"Val1-2", "Val2Name"=>"Val2-2", "..."=>"...", "ValMName"=>"ValM-2"}, 
    {"KeyName"=>"Key3", "Val1Name"=>"Val1-3", "Val2Name"=>"Val2-3", "..."=>"...", "ValMName"=>"ValM-3"}, 
    {"KeyName"=>"..", "Val1Name"=>"..", "Val2Name"=>"..", "..."=>"..", "ValMName"=>".."}, 
    {"KeyName"=>"KeyN", "Val1Name"=>"Val1-N", "Val2Name"=>"Val2-N", "..."=>"...", "ValMName"=>"ValM-N"}] 

scores_hash_array現在已經在表的每一行的哈希值。

+0

這是一個很好的答案,非常感謝! 現在我將如何使用scores_hash_array中的值作爲對象的初始化值? IE obj = obj.new(key1,val1-1,val2-1,val3-1 ... valN-1) 然後根據密鑰散列這些對象。記住我完全用C語言的心態來做這件事。 – Brianne

1
f = File.open("scores.txt") #get an instance of the file 
first_line = f.gets.chomp #get the first line in the file (header) 
first_line_array = first_line.split(/\s+/) #split the first line in the file via whitespace(s) 
array_of_hash_maps = f.readlines.map do |line| 
         Hash[first_line_array.zip(line.split(/\s+/))] 
        end 
#read the remaining lines of the file via `IO#readlines` into an array, split each read line by whitespace(s) into an array, and zip the first line with them, then convert it into a `Hash` object, and return a collection of the `Hash` objects 
f.close #close the file 

puts array_of_hash_maps #print the collection of the Hash objects to stdout 
+0

這正是我所需要的,非常感謝。 Ruby與我所做過的每件事都截然不同。 :) – Brianne

+1

無需保持文件打開你可以使用'File.readlines'直接讀取整個數組到數組中# – engineersmnky

+0

@engineersmnky你需要第一行使用一個鍵,這就是'first_line = f.gets.chomp'並且剩下的行 – bjhaid

0

你可以嘗試這樣的事情: -

enter code here 
fh = File.open("scores.txt","r") 
rh={} #result Hash 
fh.readlines.each{|line| 
kv=line.split(/\s+/) 
puts kv.length 
rh[kv[0]] = kv[1..kv.length-1].join(",") #***store the values joined by "," 
} 
puts rh.inspect 
fh.close 

如果你想獲得值的數組,通過 RH [KV [0] = KV [替換循環的最後一行1..kv.length-1]

+0

這有助於很多!非常感謝! :) – Brianne