PHP - создать один массив из многомерного массива на основе имени ключа - PullRequest
1 голос
/ 14 сентября 2011

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

Внешний сервис передает мне следующий многомерный массив.

$mArray = Array (
  [success] => 1
  [errors] => 0
  [data] => Array (
    [0] => Array (
      [email] => me@example.com
      [id] => 123456 
      [email_type] => html 
      [ip_opt] => 10.10.1.1 
      [ip_signup] => 
      [member_rating] => X 
      [info_changed] => 2011-08-17 08:56:51 
      [web_id] => 123456789
      [language] =>
      [merges] => Array (
        [EMAIL] => me@example.com
        [NAME] => Firstname 
        [LNAME] => Lastname 
        [ACCOUNT] => ACME Ltd 
        [ACCMANID] => 123456adc 
        [ACCMANTEL] => 1234 123456 
        [ACCMANMAIL] => an.other@example.com
        [ACCMANFN] => Humpty
        [ACCMANLN] => Dumpty 
      )
      [status] => unknown
      [timestamp] => 2011-08-17 08:56:51
      [lists] => Array ( ) 
      [geo] => Array ( ) 
      [clients] => Array ( ) 
      [static_segments] => Array ( )
    ) 
  ) 
)

Единственная информация, которая меня интересует, - это пары ключ / значение, которые содержатся в массиве под именем «merges». Это примерно третий массив. Имя ключа массива всегда будет называться слиянием, но нет никакой гарантии, что его местоположение в массиве не будет перемещено. Количество пар ключ / значение в массиве слияний также может изменяться.

Я думаю, что мне нужна функция для array_walk_recursive ($ mArray, "myfunction", $ search); где $ search содержит строку для имени ключа (слияния), который я ищу. Ему нужно пройти по массиву, пока он не найдет ключ, проверить, что он содержит массив, а затем (сохранив ключи) вернуть каждую пару ключ / значение в один массив.

Итак, для ясности, вывод функции вернется:

    $sArray = Array (
      [EMAIL] => me@example.com
      [NAME] => Firstname 
      [LNAME] => Lastname 
      [ACCOUNT] => ACME Ltd 
      [ACCMANID] => 123456adc 
      [ACCMANTEL] => 1234 123456 
      [ACCMANMAIL] => an.other@example.com 
      [ACCMANFN] => Humpty 
      [ACCMANLN] => Dumpty
    )

Затем я могу перейти к следующему этапу в моем проекте, который заключается в сравнении ключей в одном массиве слияний с идентификаторами элементов, полученными из анализатора HTML DOM, и замене значений атрибутов на значения, содержащиеся в одном массиве.

Мне, вероятно, нужен цикл foreach. Я знаю, что могу использовать is_array, чтобы проверить, является ли $ search массивом. Он объединяет все это, с чем я борюсь.

Спасибо за вашу помощь.

Ответы [ 6 ]

1 голос
/ 14 сентября 2011

Будет ли это работать?

function find_merges($arr)
{
  foreach($arr as $key => $value){
    if($key == "merges") return $value;
    if(is_array($value)){
      $ret = find_merges($value);
      if($ret) return $ret;
    }
  }
  return false;
}

Будет выполняться поиск в глубину до тех пор, пока у вас не закончатся ключи или вы не найдете один со значением merges.Он не будет проверять, является ли merges массивом.Попробуйте и дайте мне знать, если это работает.

0 голосов
/ 08 сентября 2017

array_walk_recursive() отлично подходит для этой задачи!Ему не важно, на каком уровне находятся пары ключ-значение, и он только перебирает «конечные узлы», поэтому нет необходимости проверять, содержит ли элемент строку.Внутри функции я просто сравниваю ключи с массивом игл, чтобы сгенерировать одномерный массив результатов ($sArray).

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

Код: ( Демо )

$needles=['EMAIL','NAME','LNAME','ACCOUNT','ACCMANID','ACCMANTEL','ACCMANMAIL','ACCMANFN','ACCMANLN'];
array_walk_recursive($mArray,function($v,$k)use(&$sArray,$needles){if(in_array($k,$needles))$sArray[$k]=$v;});
var_export($sArray);

Вывод:

array (
  'EMAIL' => 'me@example.com',
  'NAME' => 'Firstname',
  'LNAME' => 'Lastname',
  'ACCOUNT' => 'ACME Ltd',
  'ACCMANID' => '123456adc',
  'ACCMANTEL' => '1234 123456',
  'ACCMANMAIL' => 'an.other@example.com',
  'ACCMANFN' => 'Humpty',
  'ACCMANLN' => 'Dumpty',
)
0 голосов
/ 15 сентября 2011

Вот функция общего назначения, которая будет проходить через вложенный массив и возвращать значение, связанное с первым появлением предоставленного ключа. Это позволяет использовать целочисленные или строковые ключи. Если соответствующий ключ не найден, возвращается false.

// return the value a key in the supplied array  
function get_keyval($arr,$mykey)
{  
    foreach($arr as $key => $value){
        if((gettype($key) == gettype($mykey)) && ($key == $mykey)) {
            return $value;
        }
        if(is_array($value)){
            return get_keyval($value,$mykey);               
        }
    }
    return false;
}

// test it out
$myArray = get_keyval($suppliedArray, "merges");
foreach($myArray as $key => $value){
    echo "$key = $value\n";
}
0 голосов
/ 14 сентября 2011

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

$search = new RegexIterator(
    new RecursiveIteratorIterator(
        new ParentIterator(new RecursiveArrayIterator($array)),
        RecursiveIteratorIterator::SELF_FIRST),
    '/^merges$/D', RegexIterator::MATCH, RegexIterator::USE_KEY
);
$search->rewind();
$merges = $search->current();
0 голосов
/ 14 сентября 2011

То есть вы хотите получить доступ к массиву внутри массива в массиве?

$mergeArray = NULL;
foreach($mArray['data'] as $mmArray)
    $mergeArray[] = $mmArray['merges'];

Что-то подобное? Если merges всегда три в глубине, я не понимаю, зачем вам рекурсия. В противном случае смотрите другие ответы.

0 голосов
/ 14 сентября 2011

Рекурсивная функция может сделать это.Возвращает массив или FALSE при ошибке.

function search_sub_array ($array, $search = 'merges') {
  if (!is_array($array)) return FALSE; // We're not interested in non-arrays
  foreach ($array as $key => $val) { // loop through array elements
    if (is_array($val)) { // We're still not interested in non-arrays
      if ($key == $search) {
        return $val; // We found it, return it
      } else if (($result = search_sub_array($array)) !== FALSE) { // We found a sub-array, search that as well
        return $result; // We found it, return it
      }
    }
  }
  return FALSE; // We didn't find it
}

// Example usage
if (($result = search_sub_array($myArray,'merges')) !== FALSE) {
  echo "I found it! ".print_r($result,TRUE);
} else {
  echo "I didn't find it :-(";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...