2009-08-03 11 views
3

Salut à tous, j'ai une très vaste gamme de revenir comme résultats de la recherche et je veux faire ce qui suit:Array PHP Parsing

Promenade dans le tableau et pour chaque enregistrement avec les mêmes ajouter « spubid » les touches suivantes/vals: "sfirst, smi, slast" au membre du groupe parent dans ce cas, $ a [0]. Donc le résultat serait de laisser $ a [0] intacte mais d'y ajouter les valeurs de sfirst, smi et slast des autres membres du tableau (puisqu'ils ont tous le même "spubid"). Je pense que l'ajout de la valeur clé (1, 2, 3) à la clé associée (sfirst1 => "J.", smi1 => "F.", Slast1 => "Kennedy") serait bien. Je voudrais alors DROP (unset()) le reste des membres dans le tableau avec ce "spubid". Voici un exemple simplifié du tableau Je reviens et dans cet exemple tous les enregistrements ont le même « spubid »:

Array ( 
    [0] => 
    Array ( 
     [spubid] => A00502 
     [sfirst] => J. 
     [smi] => A. 
     [slast] => Doe 
    [1] => 
    Array ( 
     [spubid] => A00502 
     [sfirst] => J. 
     [smi] => F. 
     [slast] => Kennedy 
    [2] => 
    Array ( 
     [spubid] => A00502 
     [sfirst] => B. 
     [smi] => F. 
     [slast] => James 
    [3] => 
    Array ( 
     [spubid] => A00502 
     [sfirst] => S. 
     [smi] => M. 
     [slast] => Williamson 
    ) 
    ) 

Donc, en substance, je veux garder un $ [0], mais ajouter de nouvelles touches => lui attribue des valeurs (sfirst $ key, smi $ key, slast $ key) et ajoute les valeurs de "sfirst, smi, slast" à TOUS les membres avec le même "spubid" puis unset $ a [1] - [3].

Juste pour clarifier mon résultat final idéal serait:

Array ( 
    [0] => 
    Array ( 
     [spubid] => A00502 
     [sfirst] => J. 
     [smi] => A. 
     [slast] => Doe 
     [sfirst1] => J. 
     [smi1] => F. 
     [slast1] => Kennedy 
     [sfirst2] => B. 
     [smi2] => F. 
     [slast2] => James 
     [sfirst3] => S. 
     [smi3] => M. 
     [slast3] => Williamson 
    ) 
) 

Dans la plupart des cas, je vais avoir un commencer éventail beaucoup plus grand avec qui comprend une multitude de l ' « spubid », mais 99% des publications ont plus d'un auteur, cette routine serait très utile pour nettoyer les résultats et faciliter le processus d'analyse.

*** MISE À JOUR

Je pense de plus en simplifiant mon exemple, je peux avoir fait des choses pas claires. J'aime les réponses de Chacha102 et de zombat, mais mon "tableau parent" contient beaucoup plus qu'un simple pubid, qui est juste la clé primaire. Je dois retenir beaucoup d'autres données de cet enregistrement, une petite partie de c'est la suivante:

[spubid] => A00680 
[bactive] => t 
[bbatch_import] => t 
[bincomplete] => t 
[scitation_vis] => I,X 
[dentered] => 2009-08-03 12:34:14.82103 
[sentered_by] => pubs_batchadd.php 
[drev] => 2009-08-03 12:34:14.82103 
[srev_by] => pubs_batchadd.php 
[bpeer_reviewed] => t 
[sarticle] => A case study of bora-driven flow and density changes on the Adriatic shelf (January 1987) 
. 
. 
. 
. 
. 

Il y a environ 40 colonnes qui reviennent à chaque requête de recherche. Plutôt que de les coder en dur comme le font ces exemples avec le pubid, comment puis-je les inclure tout en faisant les changements comme vous l'avez suggéré. Créer un tableau multidimensionnel (comme vous avez tous les deux suggéré) avec les auteurs faisant partie de la multi-dimension est parfaitement bien, merci à tous les deux pour la suggestion.

**** MISE À JOUR:

Voici ce que je me suis installé sur une solution, très simple et fait le travail bien. Je finis par créer un tableau multidimensionnel afin que les auteurs soient dissous.

sur une solution simplifiée:

$apubs_final = array(); 
$spubid = NULL; 
$ipub = 0; 

foreach($apubs as $arec) 
{ 
    if($spubid != $arec['spubid']) 
    { 
    $ipub++; 
    $apubs_final[$ipub] = $arec; 
    // insert UNSET statements here for author data 
    $iauthor = 0; 
    $spubid = $arec['spubid']; 
    } 
    $iauthor++; 
    $apubs_final[$ipub]['authors'][$iauthor]['sauthor_first'] = $arec['sfirst']; 
} 

Merci à tous ceux qui ont répondu, votre aide est/a été très appréciée!

+1

C'est une commande importante. –

+0

Serait-il plus facile d'obtenir un tableau de tableaux d'auteurs, chacun contenant sfirst, smi et slast? –

+0

Là, je l'ai fait dans les deux sens pour vous sur ma réponse au cas où vous êtes ouvert à un format différent. –

Répondre

3
// First, probably the more parsable way. 
foreach($array as $key => $values) 
{ 
    $end[$spuid] = $values; 
    $spuid = $values['spuid'] 
    $end[$spuid]['authors'][] = array('sfirst' => $values['sfirst'], 
          'smi' => $values['smi'], 
          'slast' => $values['slast']); 

} 

qui va obtenir un tableau comme celui-ci

Array(
    [A00502] => 
     Array(
      [supid] => A00502 
       .... other values ..... 
      [authors] => 
       Array(
       [0]=> 
         Array(
        ['sfirst'] => '', 
        ['smi'] => '', 
        ['slast'] => '') 
       ) 
     ) 
) 

Je trouve cette façon d'être beaucoup plus parse-mesure si vous prévoyez de le montrer sur une page, car il utilise des tableaux afin que vous puissiez foreach les auteurs, c'est comme ça que j'ai vu beaucoup de gens le faire pour des attributs comme ça.

Si vous voulez vraiment votre format idéal, utilisez cette après

$count = 0; 
foreach ($end as $supid => $values) 
{ 
    $other_end[$count] = $values; 
    $other_end[$count]['spuid'] = $spuid; 
    foreach($values['authors'] as $key => $author) 
    { 
     if($key == 0) 
     { 
      $suffix = ''; 
     } 
     else 
     { 
      $suffix = $key; 
     } 
     $other_end[$count]['sfirst'.$suffix] = $author['sfirst']; 
     $other_end[$count]['smi'.$suffix] = $author['smi']; 
     $other_end[$count]['slast'.$suffix] = $author['slast']; 
    } 

} 
+0

Grande solution, j'ai édité le post original parce que j'ai légèrement simplifié les choses rendant ainsi ma question globale peu claire. Je m'excuse! –

+0

Mis à jour, il est très similaire, et vous pourriez avoir quelques touches supplémentaires, mais tout sera là. –

+0

Fondamentalement, vous aurez le premier prénom et le second nom de la dernière personne du tableau, mais cela ne devrait pas l'affecter beaucoup. –

2

Pourquoi ne pas plutôt un tableau calée sur la spubid:

// assuming $array is your array: 

$storage = array(); 
foreach($array as $entry) { 
    $bid = $entry['spubid']; 
    if (!isset($storage[$bid])) { 
    // duplicate entry - taking the author out of it. 
    $stortmp = $entry; 
    unset($stortmp['sfirst'], $stortmp['smi'], $stortmp['slast']); 
    // add an authors array 
    $stortmp['authors'] = array(); 
    $storage[$bid] = $stortmp; 
    } 
    $author = array(
    'sfirst' => $entry['sfirst'], 
    'smi' => $entry['smi'], 
    'slast' => $entry['slast']); 
    $storage[$bid]['authors'][] = $author; 
} 

Maintenant, votre baie de stockage $ devrait ressembler à:

Array(
    "A00502" => Array(
    "spubid" => "A00502", 
    "authors" => Array(
     [0] => 
     Array ( 
      [sfirst] => J. 
      [smi] => A. 
      [slast] => Doe 
     [1] => 
     Array ( 
      [sfirst] => J. 
      [smi] => F. 
      [slast] => Kennedy 

Et vous pouvez facilement faire un foreach sur les auteurs pour les imprimer:En plus, vous pouvez accéder à $storage['A00502'].

MISES A JOUR POUR UN COMMENTAIRE

Il semble que votre tableau est probablement venir d'une sorte de requête SQL qui implique une jointure d'une table de publications à une table auteurs. Cela fait que votre jeu de données de résultats duplique beaucoup d'informations dont il n'a pas vraiment besoin. Il n'y a pas de raison que toutes les données de publication soient transférées/extraites de la base de données plusieurs fois. Essayez de réécrire pour obtenir une requête de tous les livres son va afficher, alors un « auteurs » requête qui fait quelque chose comme:

SELECT * FROM authors WHERE spubid IN ('A00502', 'A00503', 'A00504'); 

convertir ensuite dans ce tableau à utiliser pour votre affichage. Vos niveaux de trafic de base de données vous en seront reconnaissants.

+0

Cela ne fonctionne pas comme prévu, je transporte toujours toutes les données en double. J'ai trop simplifié mon exemple dans le message original qui, j'en suis sûr, était trompeur. J'ai depuis développé sur l'exemple. –

+0

J'ai modifié l'exemple pour vous montrer comment conserver toutes les données, mais je pense que votre problème concerne davantage votre jeu de données. Il y a une section à la fin de la réponse à ce sujet. – gnarf

+0

C'était en fait mon approche initiale, en utilisant une requête pour obtenir toutes les infos du pub puis une autre pour récupérer les auteurs. * Personnellement, j'aime mieux cette approche car vous ne faites qu'interroger la base de données pour obtenir exactement les données dont vous avez besoin. J'ai cependant été informé par les pouvoirs que je ne peux pas utiliser cette méthode et j'ai besoin de tout faire avec une seule requête. D'où le NESTED joint ... –

1

Ce code devrait fonctionner exactement comme vous l'avez spécifié. J'ai pris l'approche d'utiliser un couple de tableaux temporaires pour faire des corrélations entre les clés du tableau principal et les sous-clés spubid.

/* assume $array is the main array */ 
$array = array(
    array('spubid' => 'A00502','sfirst'=>'J.','smi'=>'A.','slast'=>'Doe'), 
    array('spubid' => 'A00502','sfirst'=>'J.','smi'=>'F.','slast'=>'Kennedy'), 
    array('spubid' => 'A00502','sfirst'=>'B.','smi'=>'F.','slast'=>'James'), 
    array('spubid' => 'BXXXXX','sfirst'=>'B.','smi'=>'F.','slast'=>'James'), 
    array('spubid' => 'A00502','sfirst'=>'S.','smi'=>'M.','slast'=>'Williamson') 
); 

//track spubid positions in the main array 
$keyPositions = array(); 
//keys to delete after array iteration 
$keyDel = array(); 
//track how many spubkey increments you've made to the fields 
$spubKeys = array(); 
//fields to copy between spubids 
$copyFields = array('sfirst','smi','slast'); 

foreach($array as $key => $subarr) 
{ 
    if (isset($subarr['spubid'])) { 
     if (isset($keyPositions[$subarr['spubid']])) { 
      //spubid already exists at a main array key, do the copy 
      $spubKey = ++$spubKeys[$subarr['spubid']]; 
      foreach($copyFields as $f) { 
       $array[$keyPositions[$subarr['spubid']]][$f.$spubKey] = $subarr[$f]; 
      } 
      $keyDel[] = $key; 
     } 
     else { 
      //First time encountering this spubid, mark the position 
      $keyPositions[$subarr['spubid']] = $key; 
      $spubKeys[$subarr['spubid']] = 0; 
     } 
    } 
} 
if (count($keyDel)) { 
    foreach($keyDel as $idx) unset($array[$idx]); 
} 

var_dump($array); 
+0

Édité le message original en raison de certaines simplifications sur les données en question. Pourriez-vous prendre un autre regard? Merci encore pour la bonne solution. –