2010-09-20 1 views
2

C'est ce que j'ai maintenant:PHP - Combiner les sous-réseaux et trier par valeur?

Array 
(
    [0] => Array 
     (
      [0] => Array 
       (
        [id] => 53 
        [date] => 18 Sep 2010 10:29 
        [user] => 52 
        [post] => ytiuy 
       ) 

      [1] => Array 
       (
        [id] => 55 
        [date] => 11 Sep 2010 11:14 
        [user] => 52 
        [post] => this is a test post :] 
       ) 

     ) 

    [1] => Array 
     (
      [0] => Array 
       (
        [id] => 56 
        [date] => 4 Sep 2010 03:19 
        [user] => 55 
        [post] => pppost :DD:D:D:D 
       ) 

     ) 

) 

Je veux enlever les deux premières « étapes » dans le tableau, puis trier le tableau par la valeur « date », comme ceci:

Array 
(
    [0] => Array 
     (
      [id] => 56 
      [date] => 4 Sep 2010 03:19 
      [user] => 55 
      [post] => pppost :DD:D:D:D 
     ) 

    [1] => Array 
     (
      [id] => 55 
      [date] => 11 Sep 2010 11:14 
      [user] => 52 
      [post] => this is a test post :] 
     ) 

    [2] => Array 
     (
      [id] => 53 
      [date] => 18 Sep 2010 10:29 
      [user] => 52 
      [post] => ytiuy 
     ) 
) 

Des idées?

Merci beaucoup, merci de votre aide! :)

EDIT: Je devrais également mentionner que la quantité de arrayitems ne sera pas toujours la même chose.

+1

Il me semble que vous pouvez répondre à votre question en regardant [Comment fusionner le sous-réseau en PHP le plus facilement?] (Http://stackoverflow.com/questions/2140503/how-to-merge-subarray- in-php-most-facilement) et [Comment trier un tableau de tableaux associatifs par valeur d'une clé donnée en PHP] (http://stackoverflow.com/questions/1597736/how-to-sort-an-array- of-associative-arrays-by-value-of-a-donnée-dans-php). –

Répondre

0

Avez-vous deux matrices? Ou plus? Sont-ils déjà triés? Si oui, vous pouvez l'utiliser pour les combiner plus efficacement. Sinon, vous devez probablement les trier en premier.

En gros:

  1. Trier vos tableaux d'entrée (en option)
  2. Numérisez vos tableaux d'entrée pour la valeur la plus basse, copier cette valeur dans votre nouveau tableau, supprimez la valeur du tableau d'entrée. Répétez l'opération jusqu'à ce que tous vos tableaux d'entrée soient vides.

Bien sûr, si vous ne vous souciez pas du tout de la performance, vous pouvez simplement combiner tous les tableaux, puis trier cela.

Et pour le tri, vous pouvez utiliser: http://www.php.net/manual/en/function.sort.php#99700

@Don Kirkby: En effet: Il est essentiellement un mergesort, mais il ne fonctionne que sur les tableaux déjà triés. Si elles ne sont pas triées, vous feriez probablement mieux de les combiner et d'utiliser quicksort à la place.

+0

Si les tableaux initiaux ne sont pas triés, le tri est-il effectué avant de les combiner plus rapidement? Je ne le pense pas, et le code est certainement plus simple à combiner, puis trier. –

3

Vous devriez pouvoir utiliser un modèle d'accumulateur avec la fonction array_merge pour fusionner tous les tableaux de niveau inférieur ensemble.

$result = array(); 
foreach ($oldarray as $child) 
{ 
    $result = array_merge($result, $child); 
} 

Enfin, vous pouvez utiliser la fonction user defined sort pour trier tout cela.

+0

La fonction array_merge était exactement ce que je cherchais. Je l'ai essayé avant de poster ici, mais je n'ai pas réussi à le faire fonctionner.J'ai oublié de faire de $ result un tableau avant la boucle. Le genre semble être plus compliqué. Est-il vraiment possible de trier s'il contient des caractères et des nombres? Merci pour le post! :) – Nike

+0

@Nike, voulez-vous dire que vos dates sont en format chaîne, pas des objets de date? Si c'est le cas, vous pouvez utiliser la fonction 'strptime' pour les analyser. Vous pouvez soit le faire dans la fonction de comparaison définie par l'utilisateur que vous passez à 'usort', soit remplacer toutes les chaînes avec des objets date avant le tri. –

+0

Désolé pour la réponse tardive. Oui, la date était dans un format de chaîne, mais je l'ai changé à un timestamp unix à la place et ça fonctionne très bien maintenant. Il est beaucoup plus facile de trier le tableau par des nombres, puis d'imprimer la date au format de date humaine pour que l'utilisateur puisse lire. Merci beaucoup, cela aurait pris des semaines sans votre aide. :) – Nike

1

Une alternative à la solution de Don Kirby serait d'utiliser un SplMaxHeap qui vous permettra d'itérer et trier en une seule fois:

class PostHeap extends SplMaxHeap 
{ 
    public function compare($post, $other) 
    { 
     return strtotime($post['date']) - strtotime($other['date']); 
    } 
} 

$postHeap = new PostHeap; 
foreach($posts as $subArray) { 
    foreach($subArray as $post) { 
     $postHeap->insert($post); 
    } 
} 

Le $postHeap contiendrait alors les postes dans l'ordre décroissant de date, par exemple date la plus récente en premier. Vous pouvez utiliser le code dans la fonction compare si vous souhaitez utiliser usort à la place. La commande sera alors ascendante.

+1

Je ne suis pas sûr, mais n'avez-vous pas besoin d'une autre boucle imbriquée pour que cela fonctionne? –

+0

@DonK merci, fondamentalement ma réponse était plus ou moins la même après correction, donc j'ai enlevé les parties en double. – Gordon