Ruby - Vergleichen Sie zwei Enumeratoren elegant

8

Ich habe zwei lange Zahlenströme aus zwei verschiedenen Quellen (Binärdaten) in Ruby (1.9.2).

Die beiden Quellen sind in Form von zwei Enumeratoren gekapselt.

Ich möchte überprüfen, dass die beiden Streams genau gleich sind.

Ich bin mit ein paar Lösungen gekommen, aber beide scheinen ziemlich unelegant.

Der erste transformiert beide einfach in ein Array:

%Vor%

Das funktioniert, aber es ist nicht besonders leistungsfähig, besonders wenn die Streams viel Information haben.

Die andere Option ist ... ugh.

%Vor%

Also, gibt es einen einfacheren, eleganteren Weg, dies zu tun?

    
kikito 26.06.2011, 19:10
quelle

5 Antworten

8

Nur ein kleiner Refactoring für Ihren Code, vorausgesetzt, Ihre Streams enthalten kein Element :eof .

%Vor%

Die Verwendung eines Schlüsselworts wie loop sollte schneller sein als die Verwendung einer Methode wie each .

    
sawa 26.06.2011, 20:11
quelle
6

Ein Element nach dem anderen zu vergleichen, ist wahrscheinlich das Beste, was Sie tun können, aber Sie können es besser machen als Ihre "ugh" -Lösung:

%Vor%

Der schwierigste Teil ist die Unterscheidung zwischen nur einem auslaufenden und einem auslaufenden Stream. Das Einfügen der StopIteration -Ausnahme in eine separate Funktion und die Verwendung des Fehlens eines Schlüssels in einem Hash ist eine ziemlich bequeme Möglichkeit, dies zu tun. Wenn Sie vals[:s1] nur überprüfen, treten Probleme auf, wenn Ihr Stream false oder nil enthält. Das Vorhandensein eines Schlüssels wird jedoch durch das Überprüfen dieses Problems behoben.

    
mu is too short 26.06.2011 20:36
quelle
2

Hier ist eine Aufnahme, indem Sie eine Alternative für Enumerable#zip erstellen, die träge arbeitet und kein ganzes Array erstellt. Es kombiniert meine Implementierung von Closures interleave und anderen zwei Antworten hier (mit Sentinel-Wert, um das Ende des% anzuzeigen co_de% wurde erreicht - die Tatsache, die das Problem verursacht, ist, dass Enumerable die next zurückspult, sobald sie das Ende erreicht hat.

Diese Lösung unterstützt mehrere Parameter, sodass Sie n -Strukturen gleichzeitig vergleichen können.

%Vor%

Wenn Sie also eine Variante von Enumerable haben, die träge funktioniert und die Iteration nicht stoppt, wenn das erste Enumerable das Ende erreicht, können Sie mit zip oder all? die entsprechenden Elemente auf Gleichheit prüfen.

%Vor%     
Mladen Jablanović 27.06.2011 07:27
quelle
1

Nach der Diskussion in den Kommentaren, hier ist zip-basierte Lösung, erste umhüllende Block-Version von zip innerhalb einer Enumerator , und dann verwenden, um entsprechende Elemente zu vergleichen.

Es funktioniert, aber Randfall ist bereits erwähnt: Wenn der erste Strom kürzer ist als der andere, werden die restlichen Elemente aus dem anderen entfernt (siehe Beispiel unten).

Ich habe diese Antwort als Community-Wiki markiert, da andere Mitglieder dies verbessern könnten.

%Vor%     
Mladen Jablanović 27.06.2011 13:44
quelle
0

Hier ist ein 2-Quellen-Beispiel, das eine Fiber / Co-Routine verwendet. Es ist ein bisschen langatmig, aber es ist sehr deutlich über sein Verhalten, das ist nett.

%Vor%     
Steve Jorgensen 06.07.2011 02:35
quelle

Tags und Links