Строительство хэшей хеси, чтобы определить наибольшую численную ценность в Ruby

StackOverflow https://stackoverflow.com/questions/4207026

  •  25-09-2019
  •  | 
  •  

Вопрос

У меня есть файл данных, который выглядит так:

FBpp0070000 acyr193594273 acyr 866
FBpp0070000 acyr193577824 acyr 536
FBpp0070000 acyr193693009 acyr 445
FBpp0070000 bomb193605819 bomb 503
FBpp0070000 bomb193676398 bomb 101
FBpp0070001 acyr193618043 acyr 316
FBpp0070001 acyr193617997 acyr 313
FBpp0070001 bomb193638865 bomb 482
FBpp0070001 locu193695159 locu 220
FBpp0070001 locu193638863 locu 220

Файл данных длиной до 45 000 строк.

Моя цель состоит в том, чтобы иметь это:

FBpp0070000 acyr193594273 acyr 866
FBpp0070000 bomb193605819 bomb 503
FBpp0070001 acyr193618043 acyr 316
FBpp0070001 bomb193638865 bomb 482
FBpp0070001 locu193695159 locu 220

То есть держать только те линии с наивысшим баллом в столбце 4, для каждого разного значения в столбце 3, для каждого значения в столбце 1.

Кроме того, проблемы, которые я вижу 1) множественные, дублирующие «ключи» в столбце 1 и 2) равные «баллы» в столбце 4; Я хочу сохранить только один экземпляр этого дубликата «оценки».

У меня в прошлом построило хеш в Perl, которое может обрабатывать несколько дублирующихся клавиш.

Вот что у меня в рубине.

hash = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc) }  
title = ''

File.open('test1.txt', 'r').each do |line|
  line.chomp!

     query, hit, taxa, score = line.split(/\s/)
     hash[query][hit][taxa] = score

 # end

#p "#{query}: #{taxa}: #{score}"

end
p hash

Итак, я надеюсь, что кто-то может помочь мне определить 1), если я действительно, делаю это правильно, и 2), если так, как это извлечь строки, которые мне нужны.

Спасибо.

Это было полезно?

Решение

Кажется, следующее делает то, что вы хотите, учитывая пример ввода, который вы дали выше. Вам нужно будет приведите данные в конце, чтобы получить нужный формат вывода.

#!/usr/bin/env ruby

require 'pp'

data = {}
File.open("input.txt", "r").each do |l| 
  l.chomp!
  query, hit, taxa, score = l.split(/\s+/)
  data[query] ||= {}
  data[query][taxa] ||= [0, nil]
  data[query][taxa] = [score.to_i, hit] if score.to_i > data[query][taxa].first
end 

pp data

Это дает:

dj2@Magnus:~/Development/test $ ./out.rb 
{"FBpp0070000"=>
  {"bomb"=>[503, "bomb193605819"], "acyr"=>[866, "acyr193594273"]},
 "FBpp0070001"=>
  {"bomb"=>[482, "bomb193638865"],
   "locu"=>[220, "locu193695159"],
   "acyr"=>[316, "acyr193618043"]}}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top