Как вы назначаете новые имена переменных, когда они уже назначены чему-то? Рубин - PullRequest
1 голос
/ 31 августа 2009

Название действительно ничего не объясняет. Моя ситуация такова, что я хотел бы прочитать файл и поместить содержимое в хеш. Теперь я хочу сделать это умным, хочу создать цикл, который открывает каждый файл в каталоге и помещает его в хеш Проблема в том, что я не знаю, как назначить имя относительно имени файла. например:

hash={}  
Dir.glob(path + "*") do |datafile|
  file = File.open(datafile)
  file.each do |line|
    key, value = line.chomp("\t")
    # Problem here is that I wish to have a different
    # hash name for every file I loop through
    hash[key]=value
  end
  file.close
end

Возможно ли это?

Ответы [ 6 ]

8 голосов
/ 31 августа 2009

Почему бы вам не использовать хэш, ключами которого являются имена файлов (в вашем случае «datafile»), а значениями которых являются хэши, в которые вы вставляете свои данные?

hash = Hash.new { |h, key| h[key] = Hash.new }  
Dir.glob(path + '*') do |datafile|
  next unless File.stat(datafile).file?
  File.open(datafile) do |file|
    file.each do |line|
      key, value = line.split("\t")
      puts key, value
      # Different hash name for every file is now hash[datafile]
      hash[datafile][key]=value
    end
  end
end
1 голос
/ 31 августа 2009

Если вы хотите создать динамическую переменную, вы также можете использовать #instance_variable_set (при условии, что переменные экземпляра также в порядке.

Dir.glob(path + "*") do |datafile|               
  file = File.open(datafile)                     
  hash = {}                                      
  file.each do |line|                            
    key, value = line.chomp("\t")                
    hash[key] = value                            
  end                                            
  instance_variable_set("@file_#{File.basename(datafile)}", hash)    
end

Это работает, только когда имя файла является допустимым именем переменной Ruby. В противном случае вам понадобится какое-то преобразование.

1 голос
/ 31 августа 2009

Вы хотите динамически создавать переменные с именами файлов, которые вы обрабатываете?

попробуйте это:

Dir.glob(path + "*") do |fileName|
  File.open(fileName) {

    # the variable `hash` and a variable named fileName will be
    # pointing to the same object... 
    hash = eval("#{fileName} = Hash.new")

    file.each do |line|
      key, value = line.chomp("\t")
      hash[key]=value
    end
  }
end

Конечно, вы должны сначала удостовериться, что вы расшифровали имя файла. Переменная с именем «bla.txt» не будет действительной в ruby, равно как и «path / to / bla.csv»

0 голосов
/ 01 сентября 2009

Теперь достаточно двух хешей. fileHash -> lineHash -> content.

0 голосов
/ 31 августа 2009

Вы можете использовать что-то вроде этого:

hash[file] = {}
hash[file][key] = value
0 голосов
/ 31 августа 2009

Не могли бы вы просто сделать следующее?

filehash = {} # after the File.open line

...
# instead of hash[key] = value, next two lines
hash[datafile] = filehash
filehash[key] = value
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...