2012-04-24 29 views
6

Có công cụ Ruby nào cho phép tôi tải một tập tin các từ viết tắt theo định dạng (Viết tắt => Abr) không? Sau đó, tôi cần phải đọc từng từ từ một tập tin khác. Nếu từ khớp với từ trong các từ viết tắt, tôi cần thay đổi từ đó thành từ viết tắt. Tôi nghĩ rằng tôi có thể sử dụng Hash nhưng tôi không biết làm thế nào để tải nó từ một tập tin.Ruby: Làm thế nào để tải một Hash từ một tập tin?

Trả lời

21

YAML là định dạng rất phổ biến để lưu trữ dữ liệu theo cách có thể được chuyển giữa các ứng dụng và ngôn ngữ lập trình. JSON là một thay thế khác, rất phổ biến trong các trang web.

Tôi sử dụng YAML cho những thứ như tệp cấu hình vì nó rất dễ đọc và sửa đổi. Ví dụ, cấu trúc này Ruby:

irb(main):002:0> foo = { 'a' => 1, 'b' => [2, 3], 'c' => { 'd' => 4, 'e' => 5 } } 
{ 
    "a" => 1, 
    "b" => [ 
     [0] 2, 
     [1] 3 
    ], 
    "c" => { 
     "d" => 4, 
     "e" => 5 
    } 
} 

Trông như thế này khi chuyển đổi sang YAML:

irb(main):003:0> puts foo.to_yaml 
--- 
a: 1 
b: 
- 2 
- 3 
c: 
    d: 4 
    e: 5 

Bạn có thể tiết kiệm đó vào một tập tin:

File.open('foo.yaml', 'w') { |fo| fo.puts foo.to_yaml } 

và đọc nó lại:

bar = YAML.load_file('foo.yaml') 
{ 
    "a" => 1, 
    "b" => [ 
     [0] 2, 
     [1] 3 
    ], 
    "c" => { 
     "d" => 4, 
     "e" => 5 
    } 
} 

Similarl y, bằng cách sử dụng JSON:

puts foo.to_json 
{"a":1,"b":[2,3],"c":{"d":4,"e":5}} 

Bạn có thể lưu JSON vào một tệp như bạn làm với YAML và sau đó tải lại nó và biến nó thành băm. Đó là một cú pháp hơi khác nhau mặc dù:

irb(main):011:0> File.open('foo.json', 'w') { |fo| fo.puts foo.to_json } 
nil 
irb(main):012:0> bar = JSON.parse(File.read('foo.json')) 
{ 
    "a" => 1, 
    "b" => [ 
     [0] 2, 
     [1] 3 
    ], 
    "c" => { 
     "d" => 4, 
     "e" => 5 
    } 
} 

Chiến thắng lớn với một trong hai là bất kỳ ngôn ngữ có thể đọc YAML hoặc JSON có thể đọc các tập tin và sử dụng dữ liệu, hoặc là đọc hoặc viết nó.

Thực hiện thay thế chuỗi rất dễ dàng khi bạn có băm, vì mã băm của Ruby String gsub hiểu được băm. Đây là từ the docs:

Nếu đối số thứ hai là một Hash, và các văn bản phù hợp là một trong những chìa khóa của nó, là giá trị tương ứng là chuỗi thay thế.

Điều này có nghĩa bạn có thể làm một cái gì đó như thế này:

foo = 'Jackdaws love my giant sphinx of quartz' 
bar = { 'quartz' => 'rosy quartz', 'sphinx' => 'panda' } 
foo.gsub(Regexp.union(bar.keys), bar) 
"Jackdaws love my giant panda of rosy quartz" 

Bạn phải xem ra va chạm từ biên giới làm thay thế, nhưng \b cờ trong một mô hình có thể được giúp đỡ. Làm cho công việc đó là một bài tập cho người đọc.

+0

Mặc dù đây là một lời giải thích tốt, tôi cho rằng việc đưa yaml hoặc json chỉ làm phức tạp một bài tập đơn giản. Tệp đã tồn tại và đã trở nên đơn giản như - một tệp văn bản được phân tách, một bản ghi trên mỗi dòng. Chỉ cần đọc các tập tin theo dòng, chia nhỏ nó, và xây dựng băm. – Jim

+0

Cảm ơn bạn! Nó hoạt động hoàn hảo ngay bây giờ. – user1128637

8

Xem Marshal.loadMarshal.dump.

Ngoài ra, bạn có thể xem xét việc tuần tự hóa băm thành tệp yaml và sau đó đọc/lưu nó qua YAML.

+0

Định dạng 'Marshal' là (hoặc có thể) cụ thể cho phiên bản Ruby đang được sử dụng và không có cách nào để đọc dữ liệu' Marshal' khi các phiên bản không khớp. Điều này làm cho nó một định dạng xấu cho serialization vào đĩa. –

0

Tôi đã tìm thấy điều này http://www.rubydoc.info/gems/bosh-director/1.1868.0/Bosh%2FDirector%2FConfig.load_hash sau khi tìm cách tự tải bản thân.

ví dụ của tôi là khi giao dịch với MongoDB trong ứng dụng Rails.

Vì vậy, tôi đặt phương thức Initialize để lấy bộ sưu tập mà tôi sẽ làm việc.

def initialize @collection = self.class.collection end

self.class đây là lớp tôi đang ở. Hãy sử dụng dân làm ví dụ.

các phương pháp tải là sau

def load_collection(file_path) 
    hash_values = self.class.load_hash(file_path) 
    @collection.insert_many(hash) 
end 

bên trong một binding.pry

[1] pry(#<People>)> file_path 
=> "people_results.json" 
[2] pry(#<People>)> hash 
=> [{"number"=>0, "first_name"=>"SHAUN", "last_name"=>"JOHNSON", "gender"=>"M", "group"=>"15 to 19", "secs"=>1464}, {"number"=>1, "first_name"=>"TUAN", "last_name"=>"JOHNSON", "gender"=>"M", "group"=>"masters", "secs"=>3994}, {"number"=>2, "first_name"=>"EARLINE", "last_name"=>"BROWN", "gender"=>"F", "group"=>"masters", "secs"=>1415}... 
[3] pry(#<People>)> self 
=> #<People:0x007fc80301b5f8 @coll=#<Mongo::Collection:0x70248510355560 namespace=test.people>> 
[4] pry(#<People>)> self.class 
=> People 

Vì vậy, trong trường hợp này, phương pháp load_hash mất một tham số, và trong trường hợp này tôi trôi qua trong một json với một số dữ liệu. Sau đó tôi chèn dữ liệu đó vào bộ sưu tập của tôi.

Các vấn đề liên quan