Aufbau eines Hashes von Hashes, um den größten numerischen Wert in Ruby zu bestimmen

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

  •  25-09-2019
  •  | 
  •  

Frage

Ich habe eine Datendatei, die so aussieht:

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

Die Datendatei ist ~ 45.000 Zeilen lang.

Mein Ziel ist es, Folgendes zu haben:

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

Das heißt, behalten Sie nur diese Zeilen mit der höchsten Punktzahl in Spalte 4 für jeden unterschiedlichen Wert in Spalte 3 für jeden Wert in Spalte 1.

Darüber hinaus sind die Probleme, die ich sehe, 1) mehrere, doppelte "Schlüssel" in Spalte 1 und 2) gleiche "Bewertungen" in Spalte 4; Ich möchte nur eine Instanz dieser doppelten "Punktzahl" behalten.

Ich habe in der Vergangenheit einen Hash in Perl gebaut, der mehrere Duplikatschlüssel verarbeiten kann.

Hier ist, was ich bisher in Ruby habe.

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

Ich hoffe also, dass mir jemand helfen könnte, 1) zu bestimmen, wenn ich in der Tat richtig vorgehen kann, und 2) wenn ja, wie ich die Linien extrahieren kann, die ich brauche.

Vielen Dank.

War es hilfreich?

Lösung

Das Folgende scheint angesichts des oben angegebenen Eingangsbeispiels zu tun, was Sie wollen. Sie müssen Daten am Ende zurückgehen, um das gewünschte Ausgabeformat abzurufen.

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

Das gibt:

dj2@Magnus:~/Development/test $ ./out.rb 
{"FBpp0070000"=>
  {"bomb"=>[503, "bomb193605819"], "acyr"=>[866, "acyr193594273"]},
 "FBpp0070001"=>
  {"bomb"=>[482, "bomb193638865"],
   "locu"=>[220, "locu193695159"],
   "acyr"=>[316, "acyr193618043"]}}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top