Parcourir des tableaux, toutes combinaisons possibles

Le
Mr Prout !
Salut !

Voilà mon problème :

J'ai repris une boutique en ligne (vente de vêtements) dont je ne dois
pas toucher à la structure principale. On m'a demandé de rajouter un
système de gestion des stocks, pour chaque combinaison de caractéristiques.

Par exemple, prenons les caractéristiques suivantes pour un vêtement donné :

-
Couleurs :
- bleu
- rouge
- vert

Tailles :
- L
- M
- XL
-

En faisant une requête en base, je crée le tableau PHP suivant :
-
$tab_stock
(
[couleur] => Array
(
[0] => bleu
[1] => rouge
[2] => vert
)

[taille] => Array
(
[0] => L
[1] => M
[2] => XL
)

)
-

Maintenant, il faut que je génère dynamiquement, et à partir de ce
tableau PHP, toutes les combinaisons possibles. A savoir :
- bleu,L
- bleu, M
- bleu, XL
- rouge, L
- rouge, M
- rouge, XL
- vert, L
- vert, M
- vert, XL

Ma question est :

Comment générer dynamiquement chaque combinaison de caractéristiques à
partir du tableau PHP précédent, sachant que *le nombre de
caractéristiques peut varier, et qu'il peut exister d'autres sortes de
caractéristiques* (par exemple, une caractéristique "matière", qui
contient "cuir, daim", etc) ?

J'ai essayé en imbriquant des boucles foreach et for, mais jamais je
n'ai réussi à trouver une solution convenable. :-(

La structure du tableau PHP doit-elle être modifiée ?
J'attends avec impatience vos lumières, @ bientôt !

Mr Prout !

--
Retrouvez et triez toutes les adresses emails éparpillées dans vos
documents, sites web, FTP, etc en un clic !
http://www.tictacmail.com
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Olivier Miakinen
Le #17882891
Bonjour mister Prout,

Le 18/11/2008 14:49, Mr Prout ! a écrit :

[...]

$tab_stock
(
[couleur] => Array
(
[0] => bleu
[1] => rouge
[2] => vert
)

[taille] => Array
(
[0] => L
[1] => M
[2] => XL
)
)
-------------

Maintenant, il faut que je génère dynamiquement, et à partir de ce
tableau PHP, toutes les combinaisons possibles. A savoir :
- bleu, L
[...]
- vert, XL



foreach ($tab_stock['couleur'] as $k1 => $couleur) {
foreach ($tab_stock['taille'] as $k2 => $taille) {
echo "- $couleur, $taillen";
}
}

Comment générer dynamiquement chaque combinaison de caractéristiques à
partir du tableau PHP précédent, sachant que *le nombre de
caractéristiques peut varier, et qu'il peut exister d'autres sortes de
caractéristiques* (par exemple, une caractéristique "matière", qui
contient "cuir, daim", etc) ?



Ah, pardon, j'ai répondu trop vite. Ce n'est pas très difficile avec une
fonction récursive, mais je répondrai plus tard, là je n'ai pas trop le
temps.

La structure du tableau PHP doit-elle être modifiée ?



Peu importe : si on a besoin d'une structure différente, rien n'empêche
de la créer à la volée, mais en fait ça ne me semble pas nécessaire.

J'attends avec impatience vos lumières, @ bientôt !



À plus tard, donc.

Mr Prout !



Ton nom est charmant. Vraiment. Surtout avec le point d'exclamation.

--



Attention, ta signature n'est pas conforme : il manque une espace après
les deux traits.

Cordialement,
--
Olivier Miakinen
Olivier Miakinen
Le #17883141
Le 18/11/2008 14:49, Mr Prout ! a écrit :
[...]

$tab_stock
(
[couleur] => Array
(
[0] => bleu
[1] => rouge
[2] => vert
)

[taille] => Array
(
[0] => L
[1] => M
[2] => XL
)

)



// Même tableau, mais avec des indices numériques (sera utile pour
// array_shift)
$tab_values = array_values($tab_stock);

[...]

Comment générer dynamiquement chaque combinaison de caractéristiques à
partir du tableau PHP précédent, sachant que *le nombre de
caractéristiques peut varier, et qu'il peut exister d'autres sortes de
caractéristiques* (par exemple, une caractéristique "matière", qui
contient "cuir, daim", etc) ?



function combine_all($tab_values, $result = '')
{
// On extrait le premier tableau, en le retirant de la table
// de tables.
$tab0 = array_shift($tab_values);

// Boucle sur toutes les valeurs de ce tableau
foreach ($tab0 as $value) {
// On concatène la nouvelle valeur avec les précédentes
if ($result) $result .= ", ";
$result .= $value;

if (count($tab_values) == 0) {
// C'était le dernier tableau, on affiche le résultat
echo "$resultn";
} else {
// On continue avec le tableau suivant
combine_all($tab_values, $result);
}
}
}
combine_all($tab_values);


(non testé)
Olivier Miakinen
Le #17883271
Le 18/11/2008 15:52, j'écrivais :

function combine_all($tab_values, $result = '')
{
// On extrait le premier tableau, en le retirant de la table
// de tables.
$tab0 = array_shift($tab_values);

// Boucle sur toutes les valeurs de ce tableau
foreach ($tab0 as $value) {
// On concatène la nouvelle valeur avec les précédentes
if ($result) $result .= ", ";
$result .= $value;

if (count($tab_values) == 0) {
// C'était le dernier tableau, on affiche le résultat
echo "$resultn";
} else {
// On continue avec le tableau suivant
combine_all($tab_values, $result);
}
}
}
combine_all($tab_values);



Désolé, il y a au moins un bug puisque j'augmente $result à chaque tour
de foreach au lieu de repartir de celui passé en paramètre. Voici une
autre tentative :

function combine_all($tab_values, $result = '')
{
// On extrait le premier tableau, en le retirant de la table
// de tables.
$tab0 = array_shift($tab_values);

// Boucle sur toutes les valeurs de ce tableau
foreach ($tab0 as $value) {
// On concatène la nouvelle valeur avec les précédentes
$res2 = $result ? "$result, $value" : $value;

if (count($tab_values) == 0) {
// C'était le dernier tableau, on affiche le résultat
echo "$res2n";
} else {
// On continue avec le tableau suivant
combine_all($tab_values, $res2);
}
}
}

(non testé)



(toujours pas testé)
Christophe Meresse
Le #17883481
On 18 nov, 15:27, Olivier Miakinen
> Comment générer dynamiquement chaque combinaison de caractéristiques à
> partir du tableau PHP précédent, sachant que *le nombre de
> caractéristiques peut varier, et qu'il peut exister d'autres sortes de
> caractéristiques* (par exemple, une caractéristique "matière", qui
> contient "cuir, daim", etc) ?

Ah, pardon, j'ai répondu trop vite. Ce n'est pas très difficile avec une
fonction récursive, mais je répondrai plus tard, là je n'ai pas trop le
temps.



Effectivement la solution pour répondre à la question telle qu'elle
est posée est la récursivité (un fonction qui va s'appeler elle même à
l'intérieur d'une boucle sur une caractéristique).

Cependant je ne suis pas certain que ça soit la meilleur solution car
le premier indice de ton tableau sera par exemple la couleur puis le
deuxième la taille, il deviendra assez compliqué de faire des
recherches sur une telle structure (par exemple "combien de pull XL me
reste t'il" -> il faudra parcourir chaque couleur). Ca va entrainer un
code bourrée de boucles et de récursivité.
Il n'y a aucune raison d'introduire cette "dissymétrie" de traitement
entre les caractéristiques.
Pourquoi ne pas faire plutôt un tableau à une dimension:

$stock[$id_unique]["couleur"] = ...
$stock[$id_unique]["taille"] = ...
$stock[$id_unique]["quantite"] = ...

Bref, l'idée est un peu de coller à ce que fait la db. Mais on
pourrait cependant même se poser la question de l'intérêt de stocker
le contenu de la db dans un tableau....à toi de voir à quel besoin
cela répondra.

Christophe
Olivier Miakinen
Le #17883611
Le 18/11/2008 16:22, Christophe Meresse a écrit :

[...] je ne suis pas certain que ça soit la meilleur solution car
le premier indice de ton tableau sera par exemple la couleur puis le
deuxième la taille, il deviendra assez compliqué de faire des
recherches sur une telle structure (par exemple "combien de pull XL me
reste t'il" -> il faudra parcourir chaque couleur).



Quel tableau ? Quelle structure ? Je n'ai strictement rien changé aux
structures de données de mister Prout, me contentant de fournir un code
qui *affiche* la combinatoire comme il l'avait demandé.

[...]
Pourquoi ne pas faire plutôt un tableau à une dimension:

$stock[$id_unique]["couleur"] = ...
$stock[$id_unique]["taille"] = ...
$stock[$id_unique]["quantite"] = ...



Euh... tu veux dire « $stock[$id_unique] = $tab_stock; » ? Non, je
suppose que non, mais je crois que tu n'as pas dû bien comprendre la
question posée, ou ma réponse...

Bref, l'idée est un peu de coller à ce que fait la db. Mais on
pourrait cependant même se poser la question de l'intérêt de stocker
le contenu de la db dans un tableau....à toi de voir à quel besoin
cela répondra.



Premièrement le stockage (d'une partie ?) de la base de données dans un
tableau a déjà été fait par mister Prout, et deuxièmement ce n'est pas à
moi de voir ce qu'il veut en faire : moi, je m'en fiche complètement !
Olivier Miakinen
Le #17883761
Le 18/11/2008 16:41, je répondais assez vertement à Christophe Meresse :

Quel tableau ? Quelle structure ? Je n'ai strictement rien changé aux
structures de données de mister Prout, me contentant de fournir un code
qui *affiche* la combinatoire comme il l'avait demandé.



Et aussi :

[...] je crois que tu n'as pas dû bien comprendre la
question posée, ou ma réponse...



Bon, finalement c'est moi qui ai mal lu, il n'était pas question
d'affichage mais de « rajouter un système de gestion des stocks ».

Du coup, d'abord je te présente mes excuses, et ensuite je te laisse
avec lui pour toutes les critiques et améliorations possibles car ce
n'est pas mon rayon.

Cordialement,
--
Olivier Miakinen
Mr Prout !
Le #17887351
La nouvelle vedette du web, Olivier Miakinen, a écrit :
Le 18/11/2008 16:41, je répondais assez vertement à Christophe Meresse :
Quel tableau ? Quelle structure ? Je n'ai strictement rien changé aux
structures de données de mister Prout, me contentant de fournir un code
qui *affiche* la combinatoire comme il l'avait demandé.



Et aussi :
[...] je crois que tu n'as pas dû bien comprendre la
question posée, ou ma réponse...



Bon, finalement c'est moi qui ai mal lu, il n'était pas question
d'affichage mais de « rajouter un système de gestion des stocks ».

Du coup, d'abord je te présente mes excuses, et ensuite je te laisse
avec lui pour toutes les critiques et améliorations possibles car ce
n'est pas mon rayon.

Cordialement,



En fait ce que je cherche à faire plus précisément, c'est d'insérer dans
ma table "stock", une ligne par combinaison. Ma table se présenterait
ainsi :

TABLE stock
- id_produit (Identifiant du produit, dans la table "produits")
- caracteristiques (je mets ici mes caractéristiques, séparées par une
virgule)
- quantite

Si je reprends l'exemple de mon premier message (avec un produit dont
les caractéristiques sont "couleur" et "taille"), j'insérerais ainsi
dans ma table stock les données suivantes (imaginons que l'on soit sur
le produit n° 1, et passons outre les valeurs indiquées dans le champ
"quantite", cela n'étant qu'à titre d'exemple) :
+------------------------------------------+
| id_produit | caracteristiques | quantite |
+------------------------------------------+
| 1 | bleu,M | 25 |
+------------------------------------------+
| 1 | bleu,XL | 12 |
+------------------------------------------+
| 1 | bleu,L | 0 |
+------------------------------------------+
| 1 | rouge,M | 3 |
+------------------------------------------+
| 1 | rouge,XL | 49 |
+------------------------------------------+
| 1 | rouge,L | 22 |
+------------------------------------------+
| 1 | vert,M | 105 |
+------------------------------------------+
| 1 | vert,XL | 6 |
+------------------------------------------+
| 1 | vert,L | 24 |
+------------------------------------------+

Autre exemple, si nous avions eu 3 caractéristiques pour ce produit
(couleur, taille, matière), on aurait procédé ainsi :

+------------------------------------------+
| id_produit | caracteristiques | quantite |
+------------------------------------------+
| 1 | bleu,M,coton | 25 |
+------------------------------------------+
| 1 | bleu,M,cuir | 12 |
+------------------------------------------+
| 1 | bleu,XL,coton | 0 |
+------------------------------------------+
| 1 | bleu,XL,cuir | 0 |
+------------------------------------------+
| 1 | bleu,L,coton | 0 |
+------------------------------------------+
| 1 | bleu,L,cuir | 0 |
+------------------------------------------+
(...)
et ainsi de suite pour les autres couleurs, du moment que je puisse
insérer TOUTES les possibilités de combinaisons entre chaque
caractéristiques (si j'ai 3 caractéristiques avec pour chacune 4
valeurs, je devrais ainsi ajouter dans ma table "stock" 4 puissance 3
(soit 4 x 4 x 4) = 64 lignes dans ma table (vous me dites si je me trompe).

Au final, le tableau PHP que je souhaite parcourir, me servirait à créer
ma requête d'insertion de toutes mes combinaisons, dans ma table "stock".

Ai-je été plus clair ? et surtout est-ce bien cela que vous aviez compris ?

Mr Prout !

--
Retrouvez et triez toutes les adresses emails éparpillées dans vos
documents, sites web, FTP, etc... en un clic !
http://www.tictacmail.com
CrazyCat
Le #17890541
Mr Prout ! wrote:
En fait ce que je cherche à faire plus précisément, c'est d'insérer dans
ma table "stock", une ligne par combinaison. Ma table se présenterait
ainsi :



En fait, selon la structure de tes données initiales, tu pourrais
générer automatiquement tes données avec une ou deux requètes SQL.

Imaginons que tu ais une table "couleur", une table "taille" et une
table "matiere" avec une structure du genre:
id, nom_couleur, dispo
Tu peux extraire ainsi:

SELECT c.nom_couleur, t.nom_taille, m.nom_matiere FROM couleur c LEFT
JOIN taille t ON (t.dispo=1) LEFT JOIN matiere ON (m.dispo=1) WHERE
c.dispo=1

Et si tu veux automatiquement insérer dans ta base... Un index UNIQUE
sur caracteristiques et:
REPLACE INTO table_caract SET caracteristiques=(SELECT
CONCAT(c.nom_couleur, ', ', t.nom_taille, ', ', m.nom_matiere) FROM
couleur c LEFT JOIN taille t ON (t.dispo=1) LEFT JOIN matiere ON
(m.dispo=1) WHERE c.dispo=1)

Même pas besoin de traitement PHP :)



--
Réseau IRC Francophone: http://www.zeolia.net
Aide et astuces webmasters : http://www.c-p-f.org
Communauté Francophone sur les Eggdrops: http://www.eggdrop.fr
Publicité
Poster une réponse
Anonyme