2016-06-24 5 views
0

Ich könnte diesen einen möglicherweise alleine knacken, aber mein Verstand fragt sich nach Brexit, also beschloss ich, diese netten Leute zu fragen. Ich habe dieses Array (oder SQL Ergebnisse) von Hardware-Optionen:php array in kombinationen

cId cName  vId vName 
1 Processor 679 3.5GHz 6-Core 
1 Processor 680 3.0GHz 8-Core 
1 Processor 681 2.7GHz 12-Core 
2 Memory  682 16GB 
2 Memory  683 32GB 
2 Memory  684 64GB 
5 HDD  685 256GB 
5 HDD  686 512GB 
5 HDD  687 1TB 
11 Graphics 688 D500 with 3GB 
11 Graphics 689 D700 with 6GB 

und ich bin auf der Suche nach dem effektivstenen Weg, um alle Kombinationen von Optionen zur Liste, beginnend mit

3.5GHz 6-Core, 16GB, 256GB, D500 with 3GB 

und endend mit

2.7GHz 12-Core, 64GB, 1TB, D700 with 6GB 

was ist, glaube ich, 54 Zeilen. Gibt es einen schnellen Weg mit PHP?

Oder in MySQL. Die Eingabedaten sind tatsächlich in zwei Tabellen - eine Tabelle hat Kategorie-IDs und Namen, und eine andere hat Kategorie-IDs, Wert-IDs und Wertnamen (es gibt natürlich auch Modell-IDs für andere Computer, aber lasst uns einfach bleiben mit diesem Mac Pro für jetzt).

Edit: Bitte beachten Sie dass die Anzahl der Hardware-Kategorien ist flexible - zB ein MacBook nur Speicher und HDD Optionen haben könnten. Die Anzahl der Kategorien sollte nicht begrenzt sein.

Das ist viel allgemeineren Eingang:

c1 = array (v1, v2) 
c2 = array (v3, v4, v5) 

wo die Zahl der beiden Kategorien oder Werte innerhalb einer Kategorie, flexibel ist. Das ist also das Ergebnis, sechs Kombinationen von Werten:

c1 v1, c2 v3 
c1 v1, c2 v4 
c1 v1, c2 v5 
c1 v2, c2 v3 
c1 v2, c2 v4 
c1 v2, c2 v5 

Wenn ich eine weitere Kategorie hinzufügen

c5 = array (v6, v7) 

wird es zwölf Kombinationen sein:

c1 v1, c2 v3, c5 v6 
c1 v1, c2 v3, c5 v7 
c1 v1, c2 v4, c5 v6 
c1 v1, c2 v4, c5 v7 
c1 v1, c2 v5, c5 v6 
c1 v1, c2 v5, c5 v7 
c1 v2, c2 v3, c5 v6 
c1 v2, c2 v3, c5 v7 
c1 v2, c2 v4, c5 v6 
c1 v2, c2 v4, c5 v7 
c1 v2, c2 v5, c5 v6 
c1 v2, c2 v5, c5 v7 

Die SQL-Daten

sind in zwei Tabellen. Die erste beschreibt, welche Hardware-Kategorien für bestimmtes Computermodell verfügbar sind:

modelID catID name 
1  1  Processor 
1  2  Memory 
2  1  Processor 

so hier das Computermodell 2 hat nur eine Option - verschiedener Prozessor.

Tabelle zwei beschreibt, welche Optionen verfügbar sind (optID ist einzigartig):

modelID catID optID name 
1  1  1  i3 
1  1  2  i5 
1  2  3  4GB 
1  2  4  8GB 
1  2  5  16GB 
2  1  6  i3 
2  1  7  i5 
2  1  8  i7 

Also hier haben wir einen Computer mit sechs verschiedenen Kombinationen haben kann, und zum anderen mit drei. Was ich als Ausgabe brauche, ist eine Sequenz der Kombinationen, weil ich eine API für eine SKU und den Preis dieser Kombinationen abfrage. Die Abfrage wird so etwas wie:

  1. wählen Modell modelID und Daten zurückgesetzt (zB modelID = 1?)

  2. wählen catID und optID (zB?modelID = 1 & catID = 1 & optID = 1 Prozessor Auswahl: i3)

  3. wiederholen 2 für alle verfügbaren Kategorien (also hier noch einmal mit Speicher: 4 GB)

  4. Abfrage der SKU und Preis (so jetzt wäre es Ergebnisse für i3 erhalten, 4 GB)

  5. Wiederholung von 1 für alle Kombinationen für dieses Modell - sechs mal für modelID 1 und dreimal für modelID 2.

Dies würde die gesamte Liste der Anträge auf meine Tabelle oben sein:

select?modelID=1 
choose?modelID=1&catID=1&optID=1 
choose?modelID=1&catID=2&optID=3 
price? 

select?modelID=1 
choose?modelID=1&catID=1&optID=1 
choose?modelID=1&catID=2&optID=4 
price? 

select?modelID=1 
choose?modelID=1&catID=1&optID=1 
choose?modelID=1&catID=2&optID=5 
price? 

select?modelID=1 
choose?modelID=1&catID=1&optID=2 
choose?modelID=1&catID=2&optID=3 
price? 

select?modelID=1 
choose?modelID=1&catID=1&optID=2 
choose?modelID=1&catID=2&optID=4 
price? 

select?modelID=1 
choose?modelID=1&catID=1&optID=2 
choose?modelID=1&catID=2&optID=5 
price? 

select?modelID=2 
choose?modelID=2&catID=1&optID=6 
price? 

select?modelID=2 
choose?modelID=2&catID=1&optID=7 
price? 

select?modelID=2 
choose?modelID=2&catID=1&optID=8 
price? 

Das Ergebnis neun SKUs mit den Optionen in einem Array gespeichert sein würde.

result = array (
    sku, price, modelID, array (catID => optID) 
) 

Rekursion ist wahrscheinlich der Weg zu gehen, da die Anzahl der Iterationen unsicher ist. Ich habe hier this article gefunden, was ein größerer Kandidat für ein Duplikat ist, aber ich habe meine Lösung immer noch nicht bekommen. Ich werde wahrscheinlich die Kombinationen manuell machen müssen.

Epilog

Schließlich war die Verbindung über sehr hilfreich, über Rekursion, aber es war alles tun, nicht ich wollte. Und an diesem Punkt wurde mir klar, dass ich nicht immer alle Kombinationen brauche - die API merkt sich die Position von catID, also muss ich nur die ändern, die ich muss. Und es bedeutet auch, wenige Anrufe (22 vs 33) an die API:

select?modelID=1 

choose?catID=1&optID=1 
choose?catID=2&optID=3 
price? 

choose?catID=2&optID=4 
price? 

choose?catID=2&optID=5 
price? 

choose?catID=1&optID=2 
choose?catID=2&optID=3 
price? 

choose?catID=2&optID=4 
price? 

choose?catID=2&optID=5 
price? 

select?modelID=2 

choose?catID=1&optID=6 
price? 

choose?catID=1&optID=7 
price? 

choose?catID=1&optID=8 
price? 

Und das ist der Code:

<?php 
function possibilities($input) { 
    $current = array_shift($input); 
    foreach ($current['optID'] as $optid) { 
     echo "choose?catID=", $current['catID'], "&optID=", $optid, PHP_EOL; 
     if (empty($input)) { 
      echo "price?", PHP_EOL, PHP_EOL; 
     } else { 
      possibilities($input); 
     } 
    } 
} 

$models[] = array(
    'modelID' => 1, 
    'options' => array(
     array('catID' => 1, 'optID' => array(1, 2)), 
     array('catID' => 2, 'optID' => array(3, 4, 5)) 
     ) 
    ); 
$models[] = array(
    'modelID' => 2, 
    'options' => array(
     array('catID' => 1, 'optID' => array(6, 7, 8)) 
     ) 
    ); 

foreach ($models as $model) { 
    echo "select?modelID=", $model['modelID'], PHP_EOL, PHP_EOL; 
    possibilities($model['options']); 
} 
?> 

So war ich in der Lage, alle Preise in einer Tabelle zu erhalten. Und ich musste es für alle Optionen in einer Tabellenzeile erneut analysieren. Ich bin mir sicher, dass es Leute gibt, die nicht nur wissen, wie man es in einem Schritt macht, sondern auch die Kombinationen sortiert, um ein Minimum an API-Calls zu erreichen.

+0

Vier foreach - macht es – splash58

+0

Können Sie teilen, was Sie versucht haben? Bitte lesen [wie man Fragen zu StackOverflow stellt] (http://stackoverflow.com/help/how-to-ask) –

+0

löst meine Antwort Ihr Problem? – JRsz

Antwort

-2

Nachdem Ihre Frage stark geändert wurde, versuchte ich, eine andere Lösung zu finden, aber ich scheiterte. Ich habe versucht, so etwas zu schaffen. Nach ein paar Versionen kam ich dazu:

$allCombinations = array(); 

$yourDB1[0] = array("modelID" => 1, "catID" => 1,"name" => "Processor"); 
$yourDB1[1] = array("modelID" => 1, "catID" => 2,"name" => "Memory"); 
$yourDB1[2] = array("modelID" => 2, "catID" => 1,"name" => "Processor"); 

$yourDB2[0] = array("modelID" => 1, "catID" => 1, "optID" => 1, "name" => "i3"); 
$yourDB2[1] = array("modelID" => 1, "catID" => 1, "optID" => 2, "name" => "i5"); 
$yourDB2[2] = array("modelID" => 1, "catID" => 2, "optID" => 3, "name" => "4GB"); 
$yourDB2[3] = array("modelID" => 1, "catID" => 2, "optID" => 4, "name" => "8GB"); 
$yourDB2[4] = array("modelID" => 1, "catID" => 2, "optID" => 5, "name" => "16GB"); 
$yourDB2[5] = array("modelID" => 2, "catID" => 1, "optID" => 6, "name" => "i3"); 
$yourDB2[6] = array("modelID" => 2, "catID" => 1, "optID" => 7, "name" => "i5"); 
$yourDB2[7] = array("modelID" => 2, "catID" => 1, "optID" => 8, "name" => "i7"); 

$allModels = array(); 
$sizeDB1 = count($yourDB1); 
$sizeDB2 = count($yourDB2); 

for($i = 0; $i < $sizeDB2; $i++) 
{ 
    $allModels[$yourDB2[$i]["modelID"]][] = $yourDB2[$i]; 
} 

$models = array_unique(array_keys($allModels)); 
$amountModels = count($models); 

for($i = 0; $i < $amountModels; $i++) 
{ 
    $amountCatIDs = count($allModels[$models[$i]]); 

    $allCat = array(); 
    for($j = 0; $j < $amountCatIDs; $j++) 
    { 
     $allCat[$allModels[$models[$i]][$j]["catID"]][] = 1; 
    } 

    $amountCat = count($allCat); 
    $cat = array_key($allCat); 
    for($j = 0; $j < $amountCat; $j++) 
    { 
     //Here it is tricky because of multiple possible options of hardware 
    } 
} 

Nach einer Menge Überlegung kam ich zu dem Schluss, dass eine andere Struktur hilfreich wäre. Ist es eine Option, die Struktur zu verändern? Wenn ja, empfehle ich eine Struktur wie

Model Table: 

modelID cpuIDs ramIDs hdIDs gpuIDs 
1   2,5  1,2,3 1  1,2 
2   2,5  1,2  1,2,4 2,3 
3   3,6  2,3  2,3  1,3 

CPU Table: 

cpuID name Specs  Other 
1  i3  2,0 GHz 5. generation 
2  i3  1,9 GHz 4. generation 
3  i5  2,5 GHz 4. generation 

Und der Rest wie oben. Dies wird Ihnen sehr helfen, wenn es für Sie anwendbar ist. Es gibt eine Lösung für Ihre Situation, aber ich nehme an, es ist nicht trivial und besonders schwer zu warten. Eine gut strukturierte Datenbank wird Ihnen auf lange Sicht viel Ärger ersparen, aber auch das ist nicht trivial.

Oder jedes Modell benötigt eine Standard-Hardware für jede Art, wenn sie nicht gewählt werden kann. Dies würde das Problem lösen, wo ich aufgehört habe zu arbeiten, siehe den Kommentar im Code

+0

Vielen Dank für Ihre Mühe.Leider habe ich vergessen zu erwähnen, dass die Liste sehr dynamisch ist - zB hätten manche Laptops nur zwei Speicherkonfigurationen, aber sechs verschiedene Größen von HD. –

+0

In welchem ​​Format ist Ihr Array genau? Dann kann ich Ihnen etwas voll dynamischen Code geben, aber ich brauche einen Startpunkt (die Struktur). Ist es ein zweidimensionales Array, numerisch oder assoziativ, ist es eine Datenbank in der Form wie oben? Welches Format ist die gewünschte Ausgabe? – JRsz

+0

Cool, vielen Dank. Die Originaldaten sind zwei Tabellen. Ich werde die Beschreibung aktualisieren. –