[RESOLU] Organisation Array

Petit nouveau ! | 6 Messages

01 févr. 2014, 22:12

Bien le bonjour à tous,

Je viens vers vous pour un petit problème de "mise en forme" d'un Array. Modifier un Array plat vers un Array hiérarchique (arbre ou tree en anglais).
Alors pour commencer l'array plat que je doit modifier je l'obtiens avec la fonction imap_getmailboxes, j'ai remplacer cet array par la variable $folders dans le code suivant.

J'ai déjà réussi à mettre en forme mon array hiérarchique, mais pas comme je le souhaite, voici le code :
$folders = array(
 array('Name' => 'Archive', 'Value' => 'Archive', 'Attributes' => 32, 'Delimiters' => '/'),
 array('Name' => 'Folder1', 'Value' => 'Archive/Folder1', 'Attributes' => 32, 'Delimiters' => '/'),
 array('Name' => 'Folder1A', 'Value' => 'Archive/Folder1/Folder1A', 'Attributes' => 32, 'Delimiters' => '/'),
 array('Name' => 'Folder1B', 'Value' => 'Archive/Folder1/Folder1A/Folder1B', 'Attributes' => 64, 'Delimiters' => '/'),
 array('Name' => 'Folder2', 'Value' => 'Archive/Folder2', 'Attributes' => 32, 'Delimiters' => '/'),
 array('Name' => 'Folder2A', 'Value' => 'Archive/Folder2/Folder2A', 'Attributes' => 32, 'Delimiters' => '/'),
 array('Name' => 'Folder2B', 'Value' => 'Archive/Folder2/Folder2A/Folder2B', 'Attributes' => 64, 'Delimiters' => '/'),
);
 
$tree = BuildTree($folders);
var_dump($tree);
print_r($tree);
 
function BuildTree($array) {
 
    $return = array();
    foreach ($array as $value) {
     $split = '/'.preg_quote($value['Delimiters'], '/').'/';
     $parts = preg_split($split, $value['Value'], -1, PREG_SPLIT_NO_EMPTY);
        $leafpart = array_pop($parts);
        $parent = &$return;
   
        foreach ($parts as $part)
            $parent = &$parent[$part];
 
  $parent[$leafpart] = array('Name' => $value['Name'], 'Value' => $value['Value']);
    }
    return $return;
}
Avec se code on obtiens le résultat suivant :

Code : Tout sélectionner

Array ( [Archive] => Array ( [Name] => Archive [Value] => Archive [Folder1] => Array ( [Name] => Folder1 [Value] => Archive/Folder1 [Folder1A] => Array ( [Name] => Folder1A [Value] => Archive/Folder1/Folder1A [Folder1B] => Array ( [Name] => Folder1B [Value] => Archive/Folder1/Folder1A/Folder1B ) ) ) [Folder2] => Array ( [Name] => Folder2 [Value] => Archive/Folder2 [Folder2A] => Array ( [Name] => Folder2A [Value] => Archive/Folder2/Folder2A [Folder2B] => Array ( [Name] => Folder2B [Value] => Archive/Folder2/Folder2A/Folder2B ) ) ) )
Hors j'aurais voulu obtenir ceci :

Code : Tout sélectionner

Array ( [0] => Array ( [Name] => Archive [Value] => Archive [SubNode] => Array ( [0] => Array ( [Name] => Folder1 [Value] => Archive/Folder1 [SubNode] => Array ( [0] => Array ( [Name] => Folder1A [Value] => Archive/Folder1/Folder1A [SubNode] => Array ( [0] => Array ( [Name] => Folder1B [Value] => Archive/Folder1/Folder1A/Folder1B ) ) ) ) ) [1] => Array ( [Name] => Folder2 [Value] => Archive/Folder2 [SubNode] => Array ( [0] => Array ( [Name] => Folder2A [Value] => Archive/Folder2/Folder2A [SubNode] => Array ( [0] => Array ( [Name] => Folder2B [Value] => Archive/Folder2/Folder2A/Folder2B ) ) ) ) ) ) ) )
Et je parviens pas à modifier mon code pour avoir se dernier résultat.

En gros je cherche à construire l'array suivant par le biais de ma fonction BuildTree
$treefolders = array(
    array('Name' => 'Archive', 'Value' => 'Archive', 'SubNode' => 
        array(
            array('Name' => 'Folder1', 'Value' => 'Archive/Folder1', 'SubNode' =>
                array('Name' => 'Folder1A', 'Value' => 'Archive/Folder1/Folder1A', 'SubNode' =>
                    array('Name' => 'Folder1B', 'Value' => 'Archive/Folder1/Folder1A/Folder1B')
                )
            ),
            array('Name' => 'Folder2', 'Value' => 'Archive/Folder2', 'SubNode' =>
                array('Name' => 'Folder2A', 'Value' => 'Archive/Folder2/Folder2A', 'SubNode' =>
                    array('Name' => 'Folder2B', 'Value' => 'Archive/Folder2/Folder2A/Folder2B')
                )
            )
        )
    )
);
Pouvez vous m'aider résoudre se problème ?

J'espère avoir été assez claire dans mes explications, s'il y a besoin de précision ou si je me suis mal exprimé, veuillez m'en faire part, je me ferais un plaisir de vous répondre.

ViPHP
xTG
ViPHP | 7331 Messages

02 févr. 2014, 09:31

A priori remplacer :
$parent[$leafpart] = array('Name' => $value['Name'], 'Value' => $value['Value']);
par :
$parent['SubNode'][] = array('Name' => $value['Name'], 'Value' => $value['Value']);

Petit nouveau ! | 6 Messages

02 févr. 2014, 12:41

Bonjour et merci de ta réponse,

malheureusement se n'est pas aussi simple que ça ^^, bien que ton idée est, je pense, une partie de la solution.

Sur un autre forum on m'a aussi aider et on m'a répondu ceci :
function BuildTree($array) {
 
    $return = array();
 
    foreach ($array as $value) {
     $split = '/'.preg_quote($value['Delimiters'], '/').'/';
     $parts = preg_split($split, $value['Value'], -1, PREG_SPLIT_NO_EMPTY);
 
        if(array_key_exists(1, $parts)) {
            $parts[1] = ((int) str_replace('Folder', '', $parts[1])) - 1;
        }
        $leafpart = array_pop($parts);
        $parent = &$return;
 
        foreach ($parts as $part)
            $parent = &$parent[$part]['SubNode'];
            $parent[$leafpart] = array('Name' => $value['Name'], 'Value' => $value['Value']);                 
                 
         
    }
    return array_values($return);
}
Avec se code, on arrive presque à la solution que je recherche.

Si jamais j'arrive à trouver, je le post ici et si de ton coter t'arrive (ou quelqu'un d'autre) à trouver faite de même. Je galère vraiment pour faire la suite de mon projet.

Normalement j'arrive toujours à trouver sur le Net se que je veux, mais dès que sa concerne les array je suis perdu.

ViPHP
xTG
ViPHP | 7331 Messages

02 févr. 2014, 15:49

Pourquoi presque ?
Le rendu est ce que tu postes dans ton premier message après test.
Ils ont selon moi résolu ton problème. :)

Code : Tout sélectionner

= Array ( | 0 = Array ( | | Name = "Archive" | | Value = "Archive" | | SubNode = Array ( | | | 0 = Array ( | | | | Name = "Folder1" | | | | Value = "Archive/Folder1" | | | | SubNode = Array ( | | | | | Folder1A = Array ( | | | | | | Name = "Folder1A" | | | | | | Value = "Archive/Folder1/Folder1A" | | | | | | SubNode = Array ( | | | | | | | Folder1B = Array ( | | | | | | | | Name = "Folder1B" | | | | | | | | Value = "Archive/Folder1/Folder1A/Folder1B" | | | | | | | ) | | | | | | ) | | | | | ) | | | | ) | | | ) | | | 1 = Array ( | | | | Name = "Folder2" | | | | Value = "Archive/Folder2" | | | | SubNode = Array ( | | | | | Folder2A = Array ( | | | | | | Name = "Folder2A" | | | | | | Value = "Archive/Folder2/Folder2A" | | | | | | SubNode = Array ( | | | | | | | Folder2B = Array ( | | | | | | | | Name = "Folder2B" | | | | | | | | Value = "Archive/Folder2/Folder2A/Folder2B" | | | | | | | ) | | | | | | ) | | | | | ) | | | | ) | | | ) | | ) | ) )

Petit nouveau ! | 6 Messages

02 févr. 2014, 16:05

Et non ^^, si tu regarde bien

Array (
| 0 = Array (
| | Name = "Archive"
| | Value = "Archive"
| | SubNode = Array (
| | | 0 = Array (
| | | | Name = "Folder1"
| | | | Value = "Archive/Folder1"
| | | | SubNode = Array (
| | | | | Folder1A = Array (
| | | | | | Name = "Folder1A"
| | | | | | Value = "Archive/Folder1/Folder1A"
| | | | | | SubNode = Array (
| | | | | | | Folder1B = Array (
| | | | | | | | Name = "Folder1B"
| | | | | | | | Value = "Archive/Folder1/Folder1A/Folder1B"
| | | | | | | )
| | | | | | )
| | | | | )
| | | | )
| | | )
| | | 1 = Array (
| | | | Name = "Folder2"
| | | | Value = "Archive/Folder2"
| | | | SubNode = Array (
| | | | | Folder2A = Array (
| | | | | | Name = "Folder2A"
| | | | | | Value = "Archive/Folder2/Folder2A"
| | | | | | SubNode = Array (
| | | | | | | Folder2B = Array (
| | | | | | | | Name = "Folder2B"
| | | | | | | | Value = "Archive/Folder2/Folder2A/Folder2B"
| | | | | | | )
| | | | | | )
| | | | | )
| | | | )
| | | )
| | )
| )
)

Les clefs en rouge devrait être une incrémentation et non le nom du dossier.
Et j'arrive pas à rectifier se problème.

ViPHP
xTG
ViPHP | 7331 Messages

02 févr. 2014, 19:29

$folders = array(
 array('Name' => 'Archive', 'Value' => 'Archive', 'Attributes' => 32, 'Delimiters' => '/'),
 array('Name' => 'Folder1', 'Value' => 'Archive/Folder1', 'Attributes' => 32, 'Delimiters' => '/'),
 array('Name' => 'Folder1A', 'Value' => 'Archive/Folder1/Folder1A', 'Attributes' => 32, 'Delimiters' => '/'),
 array('Name' => 'Folder1B', 'Value' => 'Archive/Folder1/Folder1A/Folder1B', 'Attributes' => 64, 'Delimiters' => '/'),
 array('Name' => 'Folder3', 'Value' => 'Archive/Folder1/Folder3', 'Attributes' => 32, 'Delimiters' => '/'),
 array('Name' => 'Folder2', 'Value' => 'Archive/Folder2', 'Attributes' => 32, 'Delimiters' => '/'),
 array('Name' => 'Folder2A', 'Value' => 'Archive/Folder2/Folder2A', 'Attributes' => 32, 'Delimiters' => '/'),
 array('Name' => 'Folder2B', 'Value' => 'Archive/Folder2/Folder2A/Folder2B', 'Attributes' => 64, 'Delimiters' => '/'),
 array('Name' => 'Folder2C', 'Value' => 'Archive/Folder2/Folder2A/Folder2C', 'Attributes' => 64, 'Delimiters' => '/'),
 array('Name' => 'Archive2', 'Value' => 'Archive2', 'Attributes' => 32, 'Delimiters' => '/'),
);
 
$tree = BuildTree($folders);
echo '<pre>' . var_log($tree) . '</pre>';


function BuildTree($array) {
 
    $return = array();
 
    foreach ($array as $value) {
     $split = '/'.preg_quote($value['Delimiters'], '/').'/';
     $parts = preg_split($split, $value['Value'], -1, PREG_SPLIT_NO_EMPTY);
 
        if(array_key_exists(1, $parts)) {
            $parts[1] = ((int) str_replace('Folder', '', $parts[1])) - 1;
        }
        $leafpart = array_pop($parts);
        $parent = &$return;
 
        foreach ($parts as $part){
            $parent = &$parent[$part]['SubNode'];
        }
        
        $parent[$leafpart] = array('Name' => $value['Name'], 'Value' => $value['Value']);
    }
    $return = array_values_rec($return);
    return $return;
}

function array_values_rec($array)
{
	$array = array_values($array);
	foreach($array as $key => $value)
	{
		if( isSet($value['SubNode']) )
			$array[$key]['SubNode'] = array_values_rec($value['SubNode']);
	}
	return $array;
}

Code : Tout sélectionner

= Array ( | 0 = Array ( | | Name = "Archive" | | Value = "Archive" | | SubNode = Array ( | | | 0 = Array ( | | | | Name = "Folder1" | | | | Value = "Archive/Folder1" | | | | SubNode = Array ( | | | | | 0 = Array ( | | | | | | Name = "Folder1A" | | | | | | Value = "Archive/Folder1/Folder1A" | | | | | | SubNode = Array ( | | | | | | | 0 = Array ( | | | | | | | | Name = "Folder1B" | | | | | | | | Value = "Archive/Folder1/Folder1A/Folder1B" | | | | | | | ) | | | | | | ) | | | | | ) | | | | | 1 = Array ( | | | | | | Name = "Folder3" | | | | | | Value = "Archive/Folder1/Folder3" | | | | | ) | | | | ) | | | ) | | | 1 = Array ( | | | | Name = "Folder2" | | | | Value = "Archive/Folder2" | | | | SubNode = Array ( | | | | | 0 = Array ( | | | | | | Name = "Folder2A" | | | | | | Value = "Archive/Folder2/Folder2A" | | | | | | SubNode = Array ( | | | | | | | 0 = Array ( | | | | | | | | Name = "Folder2B" | | | | | | | | Value = "Archive/Folder2/Folder2A/Folder2B" | | | | | | | ) | | | | | | | 1 = Array ( | | | | | | | | Name = "Folder2C" | | | | | | | | Value = "Archive/Folder2/Folder2A/Folder2C" | | | | | | | ) | | | | | | ) | | | | | ) | | | | ) | | | ) | | ) | ) | 1 = Array ( | | Name = "Archive2" | | Value = "Archive2" | ) )
;)

Mammouth du PHP | 2278 Messages

02 févr. 2014, 20:20

Je ne voudrais pas avoir l'air trop grincheux, mais c'est le genre de problème qui traine dans tous les bouquins d'algorithmique, avec les fonctions de création et de parcours.
Le fin du fin c'est un arbre binaire équilibré.
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Petit nouveau ! | 6 Messages

03 févr. 2014, 11:27

Qu'une seul chose à dire ...... parfait et aussi un grand merci xTG =D>

sirakawa : moi aussi je ne voudrais pas être grincheux ^^, mais je ne comprend rien à se que tu à dit. Les bouquins de programmation j'en ais pas un seul, internet suffit, mais en plus d'algorithmique, alors la encore moins :lol:

Mammouth du PHP | 2278 Messages

03 févr. 2014, 16:33

Le fait que tu ne comprennes rien est la preuve que tu as besoin de lectures.
L'algorithmique évite de réinventer la roue de brouette quand on sait fabriques des roues lenticulaires... par exemple.
Il y a, entre autres, en ce qui concerne les arbres des algorithmes étudiés et prouvés qu'il suffit de suivre.
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Petit nouveau ! | 6 Messages

03 févr. 2014, 16:55

Non mais c'est pas possible je les attire .... :P je n'en dirai pas plus ... quoi que si.

En gros si t'as quelque chose de mieux et pour prouver ta science, sort moi un code. xTG, lui, au lieu de baragouiner, s'est efforcé de m'aider et a corrigé mon problème.

Pour finir et j'en resterai là : La culture c'est comme la confiture, moins on en a, plus on l'étale .... médite un peu.

Mammouth du PHP | 2278 Messages

03 févr. 2014, 20:36

Un objet de ce genre

Code : Tout sélectionner

noeud id_noeud id_pere id_premier_fils id_frere_droit id_frere_gauche
rendrait peut-être l'arbre plus facile à consulter
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Petit nouveau ! | 6 Messages

03 févr. 2014, 21:49

Alors là, j'ai envie de dire OUI, tu as raison .... mais (et oui il y a un mais), comme tu me l'as ci bien dit "tu as besoin de lectures" je pense que toi aussi tu aurais besoin de lectures et celle ci est relativement simple ..... c'est la mienne :D. Regarde mieux mon premier post, je vais te faciliter la tâche, je stipule dans l'exposition de mon problème, que l'array à manipuler est retourné par la fonction imap_getmailboxes, mais malheureusement cette fonction ne me retourne pas l'id_parent, etc, etc ...
Donc je veux bien ne pas réinventer la roue, mais je n'en suis pas au point de modifier et recompiler le php :mrgreen: