Ruby:如何从文件加载哈希?

问题描述:

是否有Ruby工具可以让我以(缩写=> Abr)的格式加载缩写文件?然后我需要从另一个文件中读取每个单词。如果单词与缩写词匹配,我需要将其改为缩写词。我想我可以使用哈希,但我不知道如何从文件加载它。Ruby:如何从文件加载哈希?

YAML是一种非常通用的格式,用于以可在应用程序和编程语言之间传输的方式存储数据。 JSON是另一种替代方法,这在网站中很常见。

我使用YAML来配置文件,因为它非常容易读取和修改。例如,这个红宝石结构:

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 
    } 
} 

貌似这个时候转换成YAML:

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

你可以说保存到一个文件:

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

,并在读回:

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

Similarl Y,使用JSON:

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

您可以将JSON保存到一个文件就像你使用YAML然后重新装入,并把它放回哈希值。这是一个有点不同的语法,但:

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 
    } 
} 

大赢有两种是可以读取YAML或JSON可以读取这些文件,并使用这些数据,读出或写入任何语言。

一旦你有一个散列,做字符串替换很容易,因为Ruby String的gsub理解散列。这是从the docs

如果第二个参数是散列,并且匹配的文本是它的键中的一个时,相应的 值是替换字符串。

这意味着你可以做这样的事情:

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标志图案能有所帮助。开展这项工作对读者来说是一个练习。

+0

尽管这是一个很好的解释,但我认为引入yaml或json只会使一个简单的练习复杂化。该文件已经存在,并且已经尽可能简单 - 分隔文本文件,每行一个记录。只需按行读取文件,将其拆分并构建散列。 – Jim 2012-04-25 22:02:18

+0

谢谢!它现在工作完美。 – user1128637 2012-04-26 19:15:35

参见Marshal.loadMarshal.dump

此外,您可以查看序列化散列到yaml文件,然后通过YAML读取/保存回去。

+0

'Marshal'格式是(或可能)特定于正在使用的Ruby版本,当版本不匹配时没有(理智)的方式来读取'Marshal'数据。这使它成为串行化到磁盘的不好的格式。 – 2016-01-22 04:11:04

我发现这个http://www.rubydoc.info/gems/bosh-director/1.1868.0/Bosh%2FDirector%2FConfig.load_hash 查找后如何加载哈希自己。

我的例子是在Rails应用中处理MongoDB的时候。

所以我设置了一个Initialize方法来获取我将要使用的集合。这里

def initialize @collection = self.class.collection end

self.class是我在这个类。让我们使用人作为一个例子。

的负载方法如下

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

一个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 

因此,在这种情况下,load_hash方法需要一个参数内,并且在这种情况下,我以JSON传递文件中包含一些数据。然后我将这些数据插入到我的集合中。