2009-10-29 6 views
0

J'ai les deux tableaux suivants et je voudrais les combiner. Je suis plus intéressé par les clés que par leurs valeurs. Je voudrais profiter de cetteRegroupement des clés de tableau associatif - dans le même ordre

$arr1 = array(
    'tom' => "1", 
    'sally' => "20" // unique 
    'larry' => "2", 
    'kate' => "3", 
    'dave' => "23" //unique 
); 

$arr2 = array(
    'tom' => "11", 
    'larry' => "12", 
    'drummer' => "2", // unique 
    'kate' => "7", 
    'nick' => "3"  //unique 
); 

et la transformer en quelque chose comme ça

$arr = array(
    'tom', 
    'sally',  //unique from arr1, ended up here because she's before larry 
    'drummer', //unique from arr2, ended up here because he's after larry 
    'larry', 
    'kate', 
    'dave',  //unique from arr1, ended up here because he's after the last 2 similar 
    'nick'  //unique from arr2, ended up here because he's after the last 2 similar 
); 

L'astuce est que je dois insérer tout ce qui est unique au bon endroit/ordre fondé sur ce qui est avant/après il. Merci

+2

L'ordre n'a pas de sens pour moi. Ce serait logique et réalisable si "batteur" était après "larry" dans le tableau final. Dans votre exemple, ils sont inversés par rapport au tableau original, ce qui semble plutôt arbitraire. Pourquoi n'est-ce pas aussi "nick" avant "kate" alors? –

+0

woops, faute de frappe :) wil éditer. – drummer

Répondre

2

Généralement ce que vous voulez est un algorithme non trivial. C'est ce qu'on appelle la correspondance de séquence ou le longest common subsequence problem. Je ne pense pas qu'il existe une fonction PHP intégrée pour le calculer. Une fois que vous avez les correspondances, vous pouvez traiter les éléments non appariés entre eux. Notez simplement qu'il peut y avoir plusieurs sous-séquences communes, donc il ne sera pas toujours possible que tous les éléments soient dans le même ordre que dans les tableaux originaux, si vous voulez vraiment ce genre de fusion.

Si vous ne avez pas besoin le meilleur résultat possible, vous pouvez essayer une approximation comme celui-ci, qui est à la recherche avidement pour les matchs dans les 4 éléments suivants:

$result = array(); 

$i = 0; 
$j = 0; 
while ($i < count($arr1)) { 
    // Look for a matching item in the next four items of $arr2 
    $k = 0; 
    while ($k < 4) { 
     // Do we have a match? 
     if ($arr1[$i] == $arr2[$j+$k]) { 
      // Add items from $arr2 that are before the matching item 
      while ($k-- > 0) { 
       $result[] = $arr2[$j]; 
       $j++; 
      } 
      $j++; 
      break; 
     } 
     $k++; 
    } 
    // Add the current item fro $arr1 
    $result[] = $arr1[$i]; 
    $i++; 
} 
// Add the remaining items from $arr2 
while ($j < count($arr2)) { 
    $result[] = $arr2[$j]; 
    $j++; 
} 

$result = array_unique($result); 
+0

Pour une raison quelconque, mes modifications/tentatives ne s'affichent pas dans le message. Peut-être prend un certain temps pour que le nouveau contenu édité apparaisse. Mais qu'est-ce que vous dites est juste Lukas. le batteur est maintenant après Larry comme prévu logiquement – drummer

+0

Oui, cette réponse est basée sur la version actuelle. Pour la commande précédente, vous devrez toujours obtenir le LCS, mais l'ordre des éléments non appariés ne sera pas aussi clair. –

+0

Avez-vous des idées pour me convaincre? Ce n'est pas une fonctionnalité absolument nécessaire, mais ce serait bien d'avoir, alors j'ai pensé pourquoi ne pas essayer de le faire fonctionner. Je pense que le LCS dans mon cas pourrait ne pas être nécessaire. Je pensais passer par le second tableau, voir si quelque chose est unique, puis essayer de faire correspondre où il va. – drummer

Questions connexes