PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Suche in einer Menge von Objekten


minos5000
2011-04-19, 17:05:50
Hi,

ich steh grad auf dem Schlauch, aber vielleicht ist es auch einfach schon zu spät für Gehirnakrobatik.


Folgende Situation:
Ich habe eine Menge von Objekten mit jeweils n Attributen. Auf der Menge soll gesucht werden können und zwar nach 1-n Suchparametern, ist ein Parameter nicht gesetzt muss das entsprechende Attribut ignoriert werden.



Die Anforderung entspricht also einem select auf Objekten mit AND Verknüpfung der Suchparameter. In C# würde ich Linq nehmen, aber das steht unter Delphi leider nicht zur Verfügung :(
Nun meine Frage, gibt es eine Möglichkeit, das elegant hinzubekommen ohne Monster if-Abfragen schreiben zu müssen? Mein erster Gedanke war das mit einer Hashfunktion zu machen. Aber da die Zahl der Suchparameter variieren kann, muss ich dann bei jeder Suche immer die Hashwerte erneut berechnen und das wirkt auf mich etwas unschön... Und da ich bisher nur in "modernen" Sprachen unterwegs war, und mich um so etwas noch nie kümmern musste, weiss ich auch gar nicht wie anfangen, um elegant aus Attribute einen Hashwert zu berechnen wenn ich wirklich alles selber machen muss.

Gruß
minos

PatkIllA
2011-04-19, 17:42:56
definiere Menge der Objekte und Abfragen und die Performanceansprüche.
Linq würde bei den meisten Fällen auch einfach nur alle Objekte ablatschen.
Kannst du die Daten nicht in eine Datenbank packen und dann wirklich ein Select machen?

Der_Donnervogel
2011-04-19, 20:17:19
Falls Delphi so etwas wie Reflection unterstützt könnte man folgendes machen. Man macht eine Collection die Paare aus Attributnamen und Attributwert (bzw. falls es ein komplexeres Kriterium sein soll vielleicht auch etwas in der Art eines Komperators, Functionpointer oder was auch immer die Sprache anbietet) enthalten kann. Dort legt man die Suchkriterien ab. Dann braucht man nur noch eine Schleife die über alle zu durchsuchenden Objekte iteriert, wobei dann bei jedem Objekt die Collection mit den Kriterien abgearbeitet wird (wobei man natürlich abbrechen kann wenn ein Vergleich fehlschlägt). Pseudocodemäßig wäre die Idee in etwa so:


Collection criteria = ...
Collection objectsToBeSearched = ...

foreach (object in objectsToBeSearched) {
bool isOK = true;
foreach (attribut in criteria) {
if (!attribut.IsValueOK(object.getAttribut(attribut.Name))) {
isOK = false;
break;
}
}
if (isOK) results.Add(object)
}

minos5000
2011-04-19, 20:23:53
Ich meine etwas gelesen zu haben, dass Delphi auch Reflektion kann. Bin selber nicht wirklich vertraut mit der Sprache und werde mal in die Richtung recherchieren.

@Patkilla
Datenbank wäre traumhaft, aber leider hier nicht machbar.

pest
2011-04-19, 21:33:21
muss ich dann bei jeder Suche immer die Hashwerte erneut berechnen und das wirkt auf mich etwas unschön...

das funktioniert schon. du hashst einfach für jedes attribut in eine eigene hash-tabelle
und bildest den schnitt der teilmengen bei der abfrage. das dürfte bei sehr großen datensätzen einiges beschleunigen.
das macht natürlich nur sinn wenn die attribute eine gewisse wort-breite überschreiten

wenn ein attribut aber z.b. nur nat. zahlen von 1..k enthält, könntest du alle datensätze
mit diesem attribut direkt addressieren (bei genügend kleinem k) und dich dann durch eine verkette liste hangeln.

sinnvoll bei dieser strategie ist es wenn die attribute über ihrer werte-menge rel. gleichverteilt innerhalb des datensatzes sind.

die tabellen und zeigerstruktur verbraucht nat. mehr speicherplatz, da müsste man dann über bäume nachdenken,
was aber auch nur bei bestimmt strukturierten attributen sinn macht.

die attribute würde ich außerdem geschickt in wort-breiten verpacken um die abfrage über bitshifts zu realisieren damit speicherzugriffe reduziert werden.