如何从文件中加载哈希?

Posted

技术标签:

【中文标题】如何从文件中加载哈希?【英文标题】:How to load a Hash from a File? 【发布时间】:2012-05-05 13:05:00 【问题描述】:

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

【问题讨论】:

【参考方案1】:

我找到了这个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 这里是我所在的类。让我们以 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 文件。然后我将该数据插入到我的集合中。

【讨论】:

【参考方案2】:

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 可以理解散列。这是来自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 标志可能会有所帮助。完成这项工作是读者的一项练习。

【讨论】:

虽然这是一个很好的解释,但我认为引入 yaml 或 json 只会使简单的练习复杂化。该文件已经存在,并且已经非常简单 - 一个分隔的文本文件,每行一条记录。只需逐行读取文件,将其拆分,然后构建哈希。【参考方案3】:

参见Marshal.loadMarshal.dump

此外,您可以考虑将哈希序列化为 yaml 文件,然后通过 YAML 读取/保存。

【讨论】:

Marshal 格式是(或可以是)特定于正在使用的 Ruby 版本的,并且当版本不匹配时,没有(理智的)方法来读取 Marshal 数据。这使得序列化到磁盘的格式不好。

以上是关于如何从文件中加载哈希?的主要内容,如果未能解决你的问题,请参考以下文章

如何在运行时从文件中加载 HTML 模板?

如何从 URL 在 webView 中加载 PDF?

如何在字幕文件中加载外部或自定义字体

如何从 S3 在 android 游戏中加载 swf 文件

如何从资源中加载自定义字体? [C#]

如何在ARCGIS中加载海量影像数据