9
votes

PHP - Trier la matrice multidimensionnelle par un autre tableau

J'essaie de trier un tableau multidimensionnel par un autre tableau, mais je suis jusqu'à présent court.
array_multisort semble fonctionner uniquement pour le tri réel.

Supposons J'ai ces 2 tableaux: xxx

maintenant je voudrais trier mon $ data matry en fonction de la commande dans mon $ $ commande < / Code> Array.
C'est ce que j'aimerais que le résultat soit: xxx


Je peux y accomplir facilement en exécutant une boucle imbriquée, mais cela ne ferait pas bien échouer (mon tableau est assez gros, et les tableaux ont beaucoup plus de champs).


0 commentaires

5 Réponses :


0
votes

Vous pouvez essayer d'utiliser un tri personnalisé avec Usort () . De cette façon, vous pouvez utiliser le premier tableau pour déterminer l'ordre du deuxième tableau.


2 commentaires

J'avais regardé USorte, mais un ne sais pas si / comment ça marche avec des tableaux multidimensionnels.


C'est ce qui le rend si utile. Vous définissez une fonction qui a accès à l'article complet, qu'il s'agisse d'une chaîne ou d'une matrice multidimensionnelle. Donc, dans la fonction de comparaison, vous pouvez comparer chaque index de valeurs dans le tableau de commande. Alors quelque chose comme ceci: retour (array_search ($ A ['id'], $ ordre)> array_search ($ b ['id'], $ ordre))? -1: 1;



5
votes

Il n'y a pas de fonction intégrée pour cela en PHP et je ne parviens pas à penser à une fonction personnalisée, ce qui le ferait à l'aide de USORT. Mais array_map em> est assez simple, imo, alors pourquoi ne pas l'utiliser à la place?

$sorted = array_map(function($v) use ($data) {
    return $data[$v - 1];
}, $order);


2 commentaires

Je n'ai pas capable d'utiliser des fonctions anonymes avec ma version actuelle de PHP - Comment cela fonctionnerait-il sans les utiliser?


J'ai ouvert une question ici Stackoverflow. com / questions / 13589707 / ...



7
votes

Dans votre exemple, les identifiants de la matrice $ Data sont numérotés consécutivement et à partir de 1. Le code que je donne ci-dessous suppose que c'est toujours le cas. Si ce n'est pas le cas, le code ne fonctionne pas.

<?php

$data = array(
    array('id' => 1, 'title' => 'whatever'),
    array('id' => 2, 'title' => 'whatever'),
    array('id' => 3, 'title' => 'whatever')
);

$order = array(2,3,1);
$order = array_flip($order);

function cmp($a, $b)
{
    global $order;

    $posA = $order[$a['id']];
    $posB = $order[$b['id']];

    if ($posA == $posB) {
        return 0;
    }
    return ($posA < $posB) ? -1 : 1;
}

usort($data, 'cmp');

var_dump($data);


2 commentaires

Votre dernière solution est essentiellement en train d'exécuter une boucle imbriquée en sucre. Je ne pense pas que cela va bien être bien.


@Megahit Voir le code mis à jour dans ma réponse, vous ne pouvez pas faire mieux que cela.



2
votes

Ce serait comme ça que je ferais. J'utiliserais une fonction USort personnalisée (arr_sort) en conjonction avec le tableau $ Data. XXX


1 commentaires

Fonctionne parfaitement!



2
votes

Pour ceux d'entre vous qui veulent trier les données en fonction d'une matrice avec des identifiants réels, plutôt que sur la base d'un tableau avec des index comme dans la réponse acceptée - Vous pouvez utiliser la fonction de comparaison simple suivante pour le USORT Code>:

array(3) {
  [0]=>
  array(2) {
    ["id"]=>
    int(20)
    ["title"]=>
    string(7) "Title 2"
  }
  [1]=>
  array(2) {
    ["id"]=>
    int(30)
    ["title"]=>
    string(7) "Title 3"
  }
  [2]=>
  array(2) {
    ["id"]=>
    int(10)
    ["title"]=>
    string(7) "Title 1"
  }
}


0 commentaires