PHP数组解析

问题描述:

嘿,我有一个巨大的数组回来作为搜索结果,我要做到以下几点:PHP数组解析

整个数组,然后用相同的“spubid”添加下列键每条记录行走/在这种情况下vals:“sfirst,smi,slast”到父数组成员$ a [0]。所以结果会保留$ a [0],但增加它,来自sfirst,smi的值和数组中的其他成员的值(因为它们都具有相同的“spubid”)。我认为将关键值(1,2,3)添加到关联关键字(sfirst1 =>“J.”,smi1 =>“F。”,slast1 =>“Kennedy”)会很好。然后,我想用该“spubid”删除(unset())数组中其余的成员。这里是阵列我得到回来,在这个例子中的所有记录具有相同的“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 
    ) 
    ) 

所以在本质上我要保持$ A [0],但添加新键=>值(sfirst $ key,smi $ key,slast $ key),并从所有具有相同“spubid”的成员中追加“sfirst,smi,slast”的值,然后取消设置$ a [1] - [3]。

只是为了澄清我的理想最终结果将是:

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 
    ) 
) 

在大多数情况下,我将有一个更大的阵列开始与包括“spubid”的众多,但出版物的99%的不止一个作者,所以这个例程对于清理结果和使显示的解析过程更容易很有用。

*** UPDATE

我认为在我的简化例子,我可能已经使事情不清楚。我喜欢Chacha102和Zombat的反应,但是我的“父数组”包含的不仅仅是pubid,而且恰好是主键。我需要保留大量的从记录的其他数据,这方面的一个小部分如下:

[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) 
. 
. 
. 
. 
. 

大概有40列是回来与每个搜索查询。这些例子并非像pubid那样对它们进行硬编码,而是如何在包含它们的同时仍然按照您的建议进行更改。作为多维的一部分,创建一个多维数组是非常好的,谢谢你的建议。

**** UPDATE:

这里是我看中了一个解决方案,很简单的,并得到很好地完成任务。我最终创建了一个多维数组,以便作者在那里被打破。

在简化的解决方案:

$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']; 
} 

感谢大家谁回答,你的帮助是/是非常感谢!

+1

这就是一个很高的顺序。 – 2009-08-03 22:29:09

+0

可能更容易得到一个作者数组数组,每个数组都包含sfirst,smi和slast? – 2009-08-03 22:32:52

+0

在那里,我为你做了两种方式的回答,因为你愿意转换为不同的格式。 – 2009-08-03 22:49:19

// 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']); 

} 

这将让这样的

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

,我觉得这种方式更加语法分析,如果你计划显示在页面上,因为它使用数组,所以你可以的foreach数组作者,这是我见过很多人为此类属性做的。

如果你真的想你的理想格式,使用这种事后

$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']; 
    } 

} 

为什么不反而让键入的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; 
} 

现在你的$存储阵列应该是这样的:

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

你可以很容易地做一个对作者的foreach打印它们:

foreach ($storage as $pub) { 
    echo 'Pub ID: '.$pub['spubid']."<br/>"; 
    foreach ($pub['authors'] as $author) { 
    echo 'Author: '.$author['sfirst'].' '.$author['smi'].' '.$author['slast']."<br/>"; 
    } 
} 

作为额外的奖励,您可以访问$storage['A00502']

更新的COMMENT

看来你的数组可能是由某种SQL查询涉及从出版物表中加入一个authors表来。这使得你的结果数据集重复了很多它并不需要的信息。没有理由将所有发布数据从数据库中多次传输/检索。请尝试重写它得到的所有图书的查询其将显示,然后有一个“作家”查询确实是这样的:

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

它然后转换成这个数组用于您的显示。您的数据库流量级别将感谢您。

此代码应完全按照您指定的方式工作。我采用了使用几个临时阵列来完成主阵列键和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);