PHP Разбор массива - PullRequest
       16

PHP Разбор массива

3 голосов
/ 04 августа 2009

Привет всем, у меня есть огромный массив, возвращающийся в качестве результатов поиска, и я хочу сделать следующее:

Пройдите по массиву и для каждой записи с одинаковым «spubid» добавьте следующие ключи / значения: «sfirst, smi, slast» в родительский элемент массива в этом случае, $ a [0]. Таким образом, результатом будет оставить $ a [0] в такте, но добавить к нему значения из sfirst, smi и slast от других элементов в массиве (так как все они имеют одинаковый «spubid»). Я думаю, что добавление значения ключа (1, 2, 3) к ассоциированному ключу (sfirst1 => "J.", smi1 => "F.", Slast1 => "Kennedy") было бы хорошо. Затем я хотел бы DROP (unset ()) остальных членов в массиве с этим "spubid". Вот упрощенный пример массива, который я получаю, и в этом примере все записи имеют одинаковый «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], но добавить к нему новые значения keys => (sfirst $ key, smi $ key, slast $ key) и добавить значения из «sfirst, smi, slast» из ВСЕ члены с таким же "spubid" затем сбрасывают $ a [1] - [3].

Просто чтобы уточнить мой конечный результат IDEAL будет:

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, как я могу включить их, все еще делая изменения, как вы оба предложили. Создание многомерного массива (как вы оба предложили) с участием авторов, являющихся частью многомерности, прекрасно, спасибо вам обоим за предложение.

**** ОБНОВЛЕНИЕ:

Вот то, на чем я остановился, очень простое решение, которое отлично справляется со своей работой. Я заканчиваю тем, что создаю многомерный массив, поэтому авторы разбиты.

Упрощенное решение:

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

Спасибо всем, кто откликнулся, ваша помощь очень ценится!

Ответы [ 3 ]

3 голосов
/ 04 августа 2009
// 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'] => '')
                )
        )
)

Я считаю, что этот способ гораздо лучше разбирается, если вы планируете показывать его на странице, потому что он использует массивы, чтобы вы могли обращаться к авторам, как я видел, что многие люди делают это для таких атрибутов, как этот .

Если вы действительно хотите свой идеальный формат, используйте это потом

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

}
2 голосов
/ 04 августа 2009

Почему бы вместо этого не сделать массив с ключом для 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;
}

Теперь ваш массив $ storage должен выглядеть так:

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

И вы могли бы легко сделать предисловие к авторам, чтобы напечатать их:

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'].

ОБНОВЛЕНО ДЛЯ КОММЕНТАРИИ

Похоже, что ваш массив, вероятно, исходит из некоего SQL-запроса, который включает JOIN из таблицы публикаций в таблицу авторов. Это приводит к тому, что ваш результирующий набор данных дублирует много информации, которая ему не нужна. Нет причин, чтобы все данные публикации передавались / извлекались из базы данных несколько раз. Попробуйте переписать его, чтобы получить запрос всех книг, которые он собирается отобразить, а затем запрос «авторов», который выполняет что-то вроде:

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

Затем преобразуйте его в этот массив для использования в целях отображения. Ваши уровни трафика базы данных будут вам благодарны.

1 голос
/ 04 августа 2009

Этот код должен работать точно так, как вы указали. Я использовал подход с использованием нескольких временных массивов для корреляции между ключами основного массива и подключами 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...