Bidirektionale Hash-Tabelle in Ruby

9

Ich brauche eine bidirektionale Hash-Tabelle in Ruby. Zum Beispiel:

%Vor%

Methode rfetch bedeutet umgekehrter Abruf und ist nur mein Vorschlag.

Beachten Sie drei Dinge:

  1. Wenn mehrere Schlüssel auf denselben Wert abgebildet werden, gibt rfetch alle von ihnen zurück, gepackt in Array.
  2. Wenn value ein Array ist, sucht rfetch nach seinem Parameter unter den Elementen des Arrays.
  3. Bidirektionaler Hash bedeutet, dass sowohl fetch als auch rfetch in konstanter Zeit ausgeführt werden sollten.

Existiert eine solche Struktur in Ruby (einschließlich externer Bibliotheken)?

Ich habe darüber nachgedacht, es mit zwei eindirektionalen Hashes zu implementieren, die synchronisiert werden, wenn eines davon geändert wird (und es in die Klasse packt, um Synchronisationsprobleme zu vermeiden), aber vielleicht könnte ich eine bereits existierende Lösung verwenden?

    
Mikołaj Pastuszko 03.08.2011, 12:13
quelle

5 Antworten

7

Sie könnten etwas ganz einfach selber bauen, verwenden Sie einfach ein einfaches Objekt, das zwei Hashes umschließt (einen für die Vorwärtsrichtung, einen für die Rückwärtsrichtung). Zum Beispiel:

%Vor%

Look Ups verhalten sich wie normale Hash-Lookups (weil sie normale Hash-Lookups sind). Fügen Sie einige Operatoren und vielleicht anständige to_s und inspect Implementierungen hinzu und Sie sind gut.

So etwas funktioniert so:

%Vor%

Es ist nichts falsch daran, Ihre Tools zu erstellen, wenn Sie sie brauchen.

    
mu is too short 03.08.2011, 18:32
quelle
5

In Ruby ist keine solche Struktur eingebaut.

Beachten Sie, dass Hash#rassoc etwas ähnliches tut, aber es gibt nur die erste Übereinstimmung zurück und ist linear-time:

%Vor%

Außerdem ist es nicht möglich, Ihre Anforderungen in Ruby auf vollkommen sichere Weise zu erfüllen, da Sie keine Änderungen in den Werten erkennen können, die Arrays sind. Zum Beispiel:

%Vor%

Wenn Sie jedes Mal einen Hash berechnen, um eine Änderung zu erkennen, wird Ihre Suche linear durchgeführt. Du könntest die Array-Werte duplizieren und einfrieren (wie Ruby für Hash-Schlüssel, die Strings sind!)

Was Sie anscheinend brauchen, ist eine Graph-Klasse, die eine andere API als Hash haben könnte, nein? Sie können rgl oder ähnliches auschecken, aber ich weiß nicht, wie sie implementiert sind.

Viel Glück.

    
Marc-André Lafortune 03.08.2011 14:44
quelle
1

Es gibt eine Methode Hash#invert ( Ссылка ) ) um das zu erreichen. Es werden jedoch nicht mehrere Werte einem Array zugeordnet.

    
Clemens Helm 15.03.2014 15:15
quelle
0

Versuchen Sie Folgendes:

%Vor%     
Sony Santos 03.08.2011 12:41
quelle
0

Wenn Sie an diesem Hash nicht viele Aktualisierungen vornehmen, können Sie inverthash verwenden .

    
Ken Bloom 03.08.2011 14:59
quelle

Tags und Links