Как разобрать данные из файла в хэш - PullRequest
0 голосов
/ 22 мая 2019

Я пытаюсь проанализировать и сохранить некоторые данные из файла в хэш-карту, используя не регулярные выражения, а сравнение строк, и я получаю некоторые ошибки, которые пытался исправить, но не решил проблему.

Файл имеет следующую структуру:

"key" + "double colon" + "value"

в каждой строке.Эта структура повторяется по файлу, и у всех данных есть ключ идентификатора, почти у всех есть хотя бы один ключ "is_a", а также могут быть ключи "is_obsolete" и "replace_by".

Я пытаюсьчтобы проанализировать это следующим образом:

def get_hpo_data(hpofile="hp.obo")
    hpo_data = Hash.new() #Hash map where i want to store all IDs
    File.readlines(hpofile).each do |line|
        if line.start_with? "id:" #if line is an ID
            hpo_id = line[4..13]  #Store ID value
            hpo_data[hpo_id] = Hash.new() #Setting up hash map for that ID
            hpo_data[hpo_id]["parents"] = Array.new()

        elsif line.start_with? "is_obsolete:" #If the ID is obsolete
            hpo_data[hpo_id]["is_obsolete"] = true #store value in the hash

        elsif line.start_with? "replaced_by:" #If the ID is obsolete
            hpo_data[hpo_id]["replaced_by"] = line[13..22]
            #Store the ID term it was replaced by

        elsif line.start_with? "is_a:" #If the ID has a parent ID
            hpo_data[hpo_id]["parents"].push(line[6..15])
            #Store the parent(s) in the array initialized before
        end
    end
    return hpo_data
end

Структура, которую я ожидал создать, является глобальным хешем, в котором каждый ID также является хешем с различными данными (одна строковая информация, одна логическая переменная и массив спеременная длина, зависящая от количества родителей-ID этого термина ID, но я получаю следующую ошибку:

table_combination.rb:224:in `block in get_hpo_data': undefined method `[]=' for nil:NilClass (NoMethodError)

На этот раз ошибка указывает на оператор replaced_by elsif, но ятакже получить его с любым другим оператором elsif, чтобы код не работал при разборе свойств "is_obsolete", "replace_by" и "is_a". Если я попытаюсь удалить эти операторы, код успешно создаст глобальный хэш с каждым термином IDв качестве хэша.

Я также пытался указать значения по умолчанию для каждого хэша, но это не решает проблему. Я даже получаю новую ошибку, не замеченную ранее:

table_combination.rb:233:in '[]': no implicit conversion of String into Integer (TypeError)

в этой строке:

hpo_data[hpo_id]["parents"].push(line[6..15])

Вот пример того, как файл выглядит для двух терминов, показывающих различные ключи, о которых я хочу позаботиться:

[Term]
id: HP:0002578
name: Gastroparesis
def: "Decreased strength of the muscle layer of stomach, which leads to a decreased ability to empty the contents of the stomach despite the absence of obstruction." [HPO:probinson]
subset: hposlim_core
synonym: "Delayed gastric emptying" EXACT layperson [ORCID:0000-0001-5208-3432]
xref: MSH:D018589
xref: SNOMEDCT_US:196753007
xref: SNOMEDCT_US:235675006
xref: UMLS:C0152020
is_a: HP:0002577 ! Abnormality of the stomach
is_a: HP:0011804 ! Abnormal muscle physiology

[Term]
id: HP:0002564
name: obsolete Malformation of the heart and great vessels
is_obsolete: true
replaced_by: HP:0030680

1 Ответ

0 голосов
/ 22 мая 2019

Возможно, в вашем коде скрыто больше ошибок, но одна проблема действительно состоит в том, что у вашего hpo_data нет значений по умолчанию.

Сбой вызова hpo_data[hpo_id]["replaced_by"] = line[13..22], если hpo_id не был инициализирован.

Вы можете определить hpo_data так:

hpo_data = Hash.new { |hash, key| hash[key] = {'parents' => [] } }

и удалите

hpo_data = Hash.new() #Hash map where i want to store all IDs

и

        hpo_data[hpo_id] = Hash.new() #Setting up hash map for that ID 
        hpo_data[hpo_id]["parents"] = Array.new()

Каждый раз, когда вы звоните hpo_data[hpo_id], он будет автоматически определен как {"parents"=>[]}.

Как пример:

hpo_data = Hash.new { |hash, key| hash[key] = {'parents' => [] } }
# => {} 
hpo_data[1234]
# => {"parents"=>[]} 
hpo_data[1234]["parents"] << 6
# => [6] 
hpo_data
# => {1234=>{"parents"=>[6]}} 
hpo_data[42]["is_obsolete"] = true
# => true 
hpo_data
# => {1234=>{"parents"=>[6]}, 42=>{"parents"=>[], "is_obsolete"=>true}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...