Hallo,
ich habe ein Array aus Arrays, die nach einem komplexen Filter sortiert und gefiltert werden müssen und suche noch einen guten Algorithmus dafür.
Ziel ist es eine Menge von unbekannten Einträgen nach einer definierten Priorität aufzulisten und dabei ggf. auch zu filtern.
------------------
Die Sortierung soll die Daten aufgrund eines Filters gewichten. Dieser Filter soll im Stringformat so aussehen:
K11:[1-12]:C,M,Y; MK01:*:*; *:*:*
- Jedes Filterargument ist durch ";" getrennt.
- Die Reihenfolge der Argumente, bzw. deren Sub-Argumente entscheided die Reihenfolge der Ausgabe
- Jedes Argument ist so aufgebaut: ID ':' PAGES ':' INKS
- ID ist ein string der verglichen werden muss, oder ein '*' für alle IDs.
- PAGES ist entweder ein '*' für alle Seiten oder eine Nummer oder eine Range in "[]" oder eine Kombination aus alledem. Hier ist ebenfalls die Reihenfolge wichtig, so hat z.B. bei "5,6,7,1,2,3" die Seite 5 mehr "gewicht" als die Seite 1.
- INKS verhält sich wie PAGES, hier sind jedoch wieder Strings statt Zahlen am Werk.
Ein '*' bedeutet ALLES matched. Fehlt dieser, werden die Angaben nicht in das Ergebnis übernommen.
Die zu sortierenden Daten bestehen aus 4 Angaben:
1. deren "natürliche" Reihenfolge (index im Array)
2. die ID der Seite
3. die PAGE
4. die INK
$found = array(
0 => array( id=>'MK01', page=>'15', ink=>'K' ),
1 => array( id=>'K11', page=>'4', ink=>'K' ),
2 => array( id=>'MK01', page=>'15', ink=>'C' ),
3 => array( id=>'K14', page=>'1', ink=>'M' ),
4 => array( id=>'K11', page=>'4', ink=>'C' ),
);
Mit folgendem Filter müsste das Array nach dem Sort dann so aussehen:
$filter = "K11:[1-12]:C,M,Y; MK01:*:*"
$sorted = array(
2 => array( id=>'K11', page=>'4', ink=>'C' ),
1 => array( id=>'MK01', page=>'15', ink=>'K' ),
0 => array( id=>'MK01', page=>'15', ink=>'C' ),
);
(! Die wichtigste Seite soll den höchsten Index haben um die Werte mit array_pop zu verarbeiten)
Erklärung: K11 und K14 kommen nicht, weil keine Regel existiert. K11/4/C fällt in die erste Regel, hat also die höchste Priorität.
------------------
Soweit die Einleitung. Mein bisheriger Lösungsansatz sieht so aus das ich für jedes Attribut ein "Gewicht" festlegen möchte und später diese addiere. Z.B. kann die Natürliche Reihenfolge von 1-9999 liegen. Die Farbe (INK) dann von 10000 bis 10099, die PAGE von 10100-10999 und die ID von 11000-11099.
Wenn ich also für jede gefundene Seite im $found Array anhand ihrer Werte im Vergleich zum Filter ein Gewicht für jedes Attribut errechene und diese dann addiere müsste ich eine Art Quersumme haben, die jede Seite eindeutig in Relation zu den anderen setzt. Anschliessend müsste man "nur noch" numerisch sortieren.
Zum Vergleich mit den Filterregeln müsste jede Regel dann aufgrund ihres Indexes (natürliche Folge) bewertet werden.
Hui, ich hoffe das ist nicht zu komplex um es zu verstehen. Mir qualmt schon der Kopf... :-)
ich habe ein Array aus Arrays, die nach einem komplexen Filter sortiert und gefiltert werden müssen und suche noch einen guten Algorithmus dafür.
Ziel ist es eine Menge von unbekannten Einträgen nach einer definierten Priorität aufzulisten und dabei ggf. auch zu filtern.
------------------
Die Sortierung soll die Daten aufgrund eines Filters gewichten. Dieser Filter soll im Stringformat so aussehen:
K11:[1-12]:C,M,Y; MK01:*:*; *:*:*
- Jedes Filterargument ist durch ";" getrennt.
- Die Reihenfolge der Argumente, bzw. deren Sub-Argumente entscheided die Reihenfolge der Ausgabe
- Jedes Argument ist so aufgebaut: ID ':' PAGES ':' INKS
- ID ist ein string der verglichen werden muss, oder ein '*' für alle IDs.
- PAGES ist entweder ein '*' für alle Seiten oder eine Nummer oder eine Range in "[]" oder eine Kombination aus alledem. Hier ist ebenfalls die Reihenfolge wichtig, so hat z.B. bei "5,6,7,1,2,3" die Seite 5 mehr "gewicht" als die Seite 1.
- INKS verhält sich wie PAGES, hier sind jedoch wieder Strings statt Zahlen am Werk.
Ein '*' bedeutet ALLES matched. Fehlt dieser, werden die Angaben nicht in das Ergebnis übernommen.
Die zu sortierenden Daten bestehen aus 4 Angaben:
1. deren "natürliche" Reihenfolge (index im Array)
2. die ID der Seite
3. die PAGE
4. die INK
$found = array(
0 => array( id=>'MK01', page=>'15', ink=>'K' ),
1 => array( id=>'K11', page=>'4', ink=>'K' ),
2 => array( id=>'MK01', page=>'15', ink=>'C' ),
3 => array( id=>'K14', page=>'1', ink=>'M' ),
4 => array( id=>'K11', page=>'4', ink=>'C' ),
);
Mit folgendem Filter müsste das Array nach dem Sort dann so aussehen:
$filter = "K11:[1-12]:C,M,Y; MK01:*:*"
$sorted = array(
2 => array( id=>'K11', page=>'4', ink=>'C' ),
1 => array( id=>'MK01', page=>'15', ink=>'K' ),
0 => array( id=>'MK01', page=>'15', ink=>'C' ),
);
(! Die wichtigste Seite soll den höchsten Index haben um die Werte mit array_pop zu verarbeiten)
Erklärung: K11 und K14 kommen nicht, weil keine Regel existiert. K11/4/C fällt in die erste Regel, hat also die höchste Priorität.
------------------
Soweit die Einleitung. Mein bisheriger Lösungsansatz sieht so aus das ich für jedes Attribut ein "Gewicht" festlegen möchte und später diese addiere. Z.B. kann die Natürliche Reihenfolge von 1-9999 liegen. Die Farbe (INK) dann von 10000 bis 10099, die PAGE von 10100-10999 und die ID von 11000-11099.
Wenn ich also für jede gefundene Seite im $found Array anhand ihrer Werte im Vergleich zum Filter ein Gewicht für jedes Attribut errechene und diese dann addiere müsste ich eine Art Quersumme haben, die jede Seite eindeutig in Relation zu den anderen setzt. Anschliessend müsste man "nur noch" numerisch sortieren.
Zum Vergleich mit den Filterregeln müsste jede Regel dann aufgrund ihres Indexes (natürliche Folge) bewertet werden.
Hui, ich hoffe das ist nicht zu komplex um es zu verstehen. Mir qualmt schon der Kopf... :-)
Kommentar