如何从文件中加载哈希表?

6

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

3个回答

24

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

我使用YAML来处理配置文件,因为它非常易于阅读和修改。例如,这个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
    }
}

转换为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
    }
}

同样地,使用JSON:

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

您可以像使用YAML一样将JSON保存到文件中,然后重新加载它并将其转换回哈希表。不过语法有点不同:

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` 方法可以理解哈希表。以下是来自文档的描述:
“如果第二个参数是哈希表,并且匹配的文本是其中的一个键,则相应的值将作为替换字符串。”
这意味着你可以像这样做:
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 标志可能会有所帮助。使其正常工作是读者的练习。


虽然这是一个很好的解释,但我认为引入yaml或json只会使一个简单的练习变得更加复杂。文件已经存在,并且已经尽可能简单 - 一个分隔文本文件,每行一个记录。只需逐行读取文件,拆分它并构建哈希即可。 - Jim

8
请参考Marshal.loadMarshal.dump。另外,您也可以将哈希序列化为yaml文件,然后通过YAML读取/保存它。

Marshal 格式是(或可以是)特定于使用的 Ruby 版本,当版本不匹配时,没有(明智的)方法读取 Marshal 数据。这使得它成为磁盘序列化的不良格式。 - mu is too short

0

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

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

所以我设置了一个初始化方法来获取我将要使用的集合。

def initialize @collection = self.class.collection end

这里的self.class是我所在的类。我们以People为例。

然后是以下的加载方法:

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 文件。然后将该数据插入到我的集合中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接