将哈希值保存到 Ruby 上的文件

Posted

技术标签:

【中文标题】将哈希值保存到 Ruby 上的文件【英文标题】:Saving hashes to file on Ruby 【发布时间】:2015-06-08 20:11:55 【问题描述】:

我只是在编程中迈出第一步。我刚刚完成了 Code Academy 的另一门课程。这次我被要求创建一个小型电影目录。 这是我的问题:如何在文件而不是自己的代码中保存/加载带有电影标题和评级的哈希?

这是代码现在的样子(葡萄牙语中的几句话,但你可以忽略它:

    movies = 
    Memento: 3,
    Primer: 4,
    Ishtar: 1
    

    puts "O que você gostaria de fazer?"
    puts "-- Digite 'add' para adicionar um filme."
    puts "-- Digite 'update' para atualizar um filme."
    puts "-- Digite 'display' para mostrar todos os filmes."
    puts "-- Digite 'delete' para deletar um filme."

    choice = gets.chomp.downcase
    case choice
    when 'add'
      puts "Que filme você gostaria de adicionar?"
      title = gets.chomp
      if movies[title.to_sym].nil?
        puts "Qual a nota? (Digite um número de 0 a 4.)"
        rating = gets.chomp
        movies[title.to_sym] = rating.to_i
        puts "#title foi adicionado com uma nota de #rating."
      else
        puts "Esse filme já existe na lista! Sua nota é #                        movies[title.to_sym]."
      end
    when 'update'
      puts "Que filme você gostaria de atualizar?"
      title = gets.chomp
      if movies[title.to_sym].nil?
        puts "Filme não encontrado!"
      else
        puts "Qual é a nova nota? (Digite um número de 0 a 4.)"
        rating = gets.chomp
        movies[title.to_sym] = rating.to_i
        puts "#title foi atualizado, sua nova nota é #rating."
      end
    when 'display'
      movies.each do |movie, rating|
        puts "#movie: #rating"
      end
    when 'delete'
      puts "Que filme voce gostaria de deletar?"
      title = gets.chomp
      if movies[title.to_sym].nil?
        puts "Filme não encontrado!"
      else
        movies.delete(title.to_sym)
        puts "#title foi deletado."
      end
    else
      puts "Desculpa, não entendo o que você quer."
    end

如您所见,目录包含在代码开头的哈希中,但它不保存信息。我怎样才能让它存储所有东西?

谢谢你们!

【问题讨论】:

【参考方案1】:

如果它们是简单的哈希,YAML 文件可能是一种简单的方法。

require 'yaml'

# write hash out as a YAML file
movies =  Memento: 1, Primer: 4, Ishtar: 1 
File.write('movies.yml', movies.to_yaml)

# read back in from file
from_file = YAML.load_file('movies.yml')

# use it
from_file[:Memento]
# => 1 
from_file[:Primer]
# => 4 

【讨论】:

太棒了!它对我有用。很简单 =) 谢谢!【参考方案2】:

你可以像这样简单地使用 JSON

require 'json'

FILE_PATH = "catalogue.json"

def load
  data = nil
  File.open(FILE_PATH) do |f|
    data = JSON.parse(f.read)
  end
  data
end

def save(data)
  File.open(FILE_PATH, "w+") do |f|
    f << data.to_json
  end
end

def process
  catalogue = load

  p catalogue

  catalogue["Memento"] = 4
  save(catalogue)
end

process
# => "Memento"=>3, "Primer"=>4, "Ishtar"=>1
catalogue = load

p catalogue
# "Memento"=>4, "Primer"=>4, "Ishtar"=>1

【讨论】:

【参考方案3】:

在我看来,最好的方法是使用 Marshal 方法,如此处所述Marshaling Marshal 模块以字符串形式转储对象,可以将其写入文件。读取文件并Marshal.Loading 字符串给出了原始对象。 使用Marshal.dump可以实现写入文件

例如,在您的代码中,可以使用

movies = 
Memento: 3,
Primer: 4,
Ishtar: 1

# dumping:
File.open("test.marshal", "w")|to_file| Marshal.dump(movies, to_file)
# retrieving:
p File.open("test.marshal", "r")|from_file| Marshal.load(from_file)
#gives you movies = Memento: 3,Primer: 4,Ishtar: 1

@Nick Veys 使用Yaml 解释了另一种方法,它也被人们大量使用。

类似的解释也可以在这里获得。Closest match I found

【讨论】:

以上是关于将哈希值保存到 Ruby 上的文件的主要内容,如果未能解决你的问题,请参考以下文章

Ruby .store 函数将哈希值从数组更改为单个值

Ruby - 按值按降序排序哈希值

ruby 合并哈希中的哈希值

汇总所有相似哈希键的值 Ruby

哈希键的Ruby值?

使用来自另一个哈希的新值更新了 Ruby 哈希数组