2016-04-21 6 views
0

vergleichen habe ich ein Array von Hashes wie:Ruby Wie kann ich zwei Paare von Elementen in Array von Hashes

arry = {hash1, hash2, hash3,hash4 ....hash_N} 

für jeden Hash,

hash1 ={ "deviceId"=>"868403021230682", "osVersion"=>"6.0", "deviceOS"=>"Android", 
"appVersion"=>"1.7.2", "action"=>"Enter"} 
hash2 = { "deviceId"=>"868403021230682", "osVersion"=>"6.0", "deviceOS"=>"Android", 
"appVersion"=>"1.7.2", "action"=>"Leave"} 

, weil es, dass für jeden möglich ist, Hash "action"=>"Enter" or "Leave" wird nicht immer als ein Paar angezeigt, zum Beispiel Aktion für Hash3, Hash4, Hash5 könnte alle "Enter". Meine Idee ist nur zwei Hashes in Betracht zu ziehen, die ein Paar wie hash1 und hash2 erstellen, andere aus dem Array entfernen oder sie in ein anderes Array einfügen können. so sollte das neue Array nur [hash1, hash2, hash7,hash8] enthalten, sagen wir, Hash7 und 8 sind auch ein Paar.

sollte ich each_with_index verwenden? mein Code wie folgt aus:

def get_result(doc) 
result = [] 

doc.each_slice(2).map { |pair| 
    pair.each_with_index { |element, index| 
    if (pair[index].has_value?([:action] => "enter") &&pair[index+1].has_value?([:action] => "Leave") 
     result.push(pair) 
    end 
    } 
} 
end 

aber die if Anweisung funktioniert nicht richtig, irgendwie verwirrt darüber, wie each_with_index Hoffnung zu verwenden, kann mir jemand Basierend

Antwort

1

helfen Ihre Methode erstellt auf dem Weg ist, können Sie kann es auf diese Weise tun:

def get_result(doc) 
    doc.each_sli­ce(2).to_a­.map{ |ah| ah if ah[0][:action] == 'Enter'­ && ah[1]­[:action] == 'Leave'­}.compact.flatten 
end 

Erklärung

Die v ariable doc ist ein Array von Hashes [hash1, hash2, ...] wenn wir doc.each_slice(2).to_a schaffen eine Reihe von Paar Hashes [[hash1, hash2],[hash3,hash4]...], nun zurück, wenn wir map tun und das Paar von Hashes bekommen, dass actions pro Auftrag hat (‚Enter‘, ‚Laß‘) erhalten wir eine Array mit Nullwerten wie diesem [[hash1,hash2],nil,[hash5,hash6]..]. Wir verwenden kompakt, um die nil Werte zu entfernen. jetzt das Array wie dieser [[hash1,hash2],[hash5,hash6]..] (Array von zwei Hashes) und das Ergebnis zu erwarten ist ein Array von Hashes, das ist, warum wir flatten brauchen, wird es in das Innere Array entfernen und ein Array zurück wie diese [hash1, hash2, hash5, hash6 ...]

Wenn Sie brauchen Um die Liste der gelöschten Hashes zu erhalten, wäre es besser, wenn Sie eine andere Methode hinzufügen. Andernfalls können Sie die Methode get_result zwei Arrays zurückgeben lassen.

Hier ist, wie Sie es tun können:

def get_result(doc) 
    removed_elms = [] 
    result = doc.each_sli­ce(2).to_a­.map do |ah| 
    # if you just need them different (not the first one 'Enter' and the second one 'Leave') you need to set the commented condition 
    # if ['Enter','Leave'].include?(ah[0][:action] && ah[1][:action]) && ah[0][:action] != ah[1][:action] 
    if ah[0][:action] == 'Enter'­ && ah[1]­[:action] == 'Leave' 
    ah 
    else 
    removed_elms << ah 
    nil 
    end 
    end.compact 
    [result.flatten, removed_elms.flatten] 
end 
+0

wie kann ich den verlassenen Hashes zu einem anderen Array speichern? warum muss man platt machen? Ich möchte nur die Hashes eliminieren, die nicht gepaart sind. Wenn möglich, würde es dir etwas erklären? danke – roccia

+0

@roccia ich aktualisierte meine Antwort, ich hoffe, dass das helfen wird –

+0

Danke! Es ist sehr klar! – roccia

Verwandte Themen