Construire un hachage de hachages pour déterminer la plus grande valeur numérique en ruby

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

  •  25-09-2019
  •  | 
  •  

Question

J'ai un fichier de données qui ressemble à ceci:

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

Le fichier de données est d'environ 45.000 lignes.

Mon but est d'avoir ceci:

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

C'est-à-dire de ne garder que les lignes avec le score le plus élevé dans la colonne 4, pour chaque valeur différente dans la colonne 3, pour chaque valeur dans la colonne 1.

En outre, les problèmes que je vois sont 1) multiples, dupliquer « clés » de la colonne 1 et 2) égaux « scores » dans la colonne 4; Je veux garder une seule instance de ce Dupliquer « score ».

J'ai, dans le passé, a construit un hachage en Perl qui peut gérer plusieurs clés en double.

Voici ce que j'ai jusqu'à présent rubis.

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

Alors, j'espère que quelqu'un pourrait me aider à déterminer 1) si je suis, en effet, aller à ce sujet correctement, et 2) le cas échéant, comment extraire les lignes dont j'ai besoin.

Merci.

Était-ce utile?

La solution

Ce qui suit semble faire ce que vous voulez, étant donné l'exemple d'entrée que vous avez donné ci-dessus. Vous aurez besoin de recourir données à la fin pour obtenir le format de sortie que vous voulez.

#!/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

Cela donne:

dj2@Magnus:~/Development/test $ ./out.rb 
{"FBpp0070000"=>
  {"bomb"=>[503, "bomb193605819"], "acyr"=>[866, "acyr193594273"]},
 "FBpp0070001"=>
  {"bomb"=>[482, "bomb193638865"],
   "locu"=>[220, "locu193695159"],
   "acyr"=>[316, "acyr193618043"]}}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top