Функция PHP для извлечения частей многомерного массива на основе переменных критериев - PullRequest
0 голосов
/ 15 декабря 2010

Учитывая многомерный массив, я ищу метод, который будет извлекать различные части этого массива, учитывая переменные (то есть, разные) критерии.

Например, если это мои данные:

array(
  '0' => array(
        '0' => 'aaaaaa',
        '1' => 'bbbbb',
        '2' => 'ccccc'
  ), 
  '1' => array(
        '0' => 'aa2ssa',
        '1' => 'bb3242bb,
        '2' => 'ccccc234'
  ),
  '2' => array(
        '0' => 'aaa234aa',
        '1' => 'b3242b',
        '2' => 'cewrcc'
  ),
      (etc)
)

Я хочу иметь возможность вызывать функцию

function new_array( index, sub_index )      

, который возвращает массив на основе параметров index и sub_index . Использование одних и тех же данных, но разных параметров вернет разные данные.

Пример 1

new_array( array(0, 2), ( array(1, 2), array(0, 2) ) )

Ожидаемые результаты:

array(
  '0' => array(
        '1' => 'bbbbb',
        '2' => 'ccccc'
  ), 
  '2' => array(
        '0' => 'aaa234aa',
        '2' => 'cewrcc'
  )
)

Пример 2

new_array( array(2), ( array(0, 2) ) )

Ожидаемые результаты:

array(
  '2' => array(
        '0' =>'aaa234aa',
        '1' => 'b3242b'
  )
)

Кто-нибудь знает, как это сделать? Спасибо!

Ответы [ 3 ]

2 голосов
/ 16 декабря 2010

Альтернативное решение для @ Orbling's это:

function populateData() // CHANGE ME to populate the info how you please
{
  $seed = 'abcdefghijklmnopqrstuvwxyz0123456789';
  $_ = ''; $length = rand(5,8);
  for ($__ = 0; $__ < $length; $__++) $_ .= substr($seed,rand(0,strlen($seed)),1);
  return $_;
}

function new_array()
{
  $args = func_num_args();
  if ($args == 0)
    return FALSE; // flag error if no arguments are passed

  $template = func_get_arg(0);
  if ($template == null || !is_array($template) || $args < (count($template)+1))
    return FALSE; // flag error if we don't have enough information

  $resultAry = Array();
  $arg = 1;
  foreach ($template as $t)
  {
    $resultArySub = Array();

    $templateSub = func_get_arg($arg++);
    if ($templateSub == FALSE || !is_array($templateSub)) 
      return FALSE; // error checking for valid input

    foreach ($templateSub as $tS)
      $resultArySub[$tS] = populateData();

    $resultAry[$t] = $resultArySub;
  }
  return $resultAry;
}

header('Content-Type: text/plain');
echo "your request (or so i understood):\r\n";
$test = new_array(array(0,2),array(1,2),array(0,2));
var_dump($test);

echo "\r\nextra array on end is ignored:\r\n";
$test = new_array(array(4,2),array(1,2),array(0,2),array(3,5));
var_dump($test);

echo "\r\nno data is a FALSE:\r\n";
$test = new_array();
var_dump($test);

echo "\r\ntoo few arguments for what was supplied in first argument is a FALSE:\r\n";
$test = new_array(array(1,2,3),array(4,5),array(6,7));
var_dump($test);

echo "\r\nas long as there's as \"array argument\" for every element of the \"first argument\", this will work:\r\n";
$test = new_array(array(1,2,3,4,5,6,7),array(1),array(2),array(3),array(4),array(5),array(6),array(7));
var_dump($test);

echo "\r\nall arguments must be an array\r\n";
$test = new_array(array(1,2),'not','arrays');
var_dump($test);

Результаты в массиве со случайными записями. Результатом вышесказанного будет:

your request (or so i understood):
array(2) {
  [0]=>
  array(2) {
    [1]=>
    string(8) "mjdfsmda"
    [2]=>
    string(8) "qg2bzsj6"
  }
  [2]=>
  array(2) {
    [0]=>
    string(7) "345plm8"
    [2]=>
    string(7) "1exlla6"
  }
}

extra array on end is ignored:
array(2) {
  [4]=>
  array(2) {
    [1]=>
    string(5) "0ngei"
    [2]=>
    string(5) "q6tmg"
  }
  [2]=>
  array(2) {
    [0]=>
    string(7) "4enz61q"
    [2]=>
    string(6) "6bojtn"
  }
}

no data is a FALSE:
bool(false)

too few arguments for what was supplied in first argument is a FALSE:
bool(false)

as long as there's as "array argument" for every element of the "first argument", this will work:
array(7) {
  [1]=>
  array(1) {
    [1]=>
    string(7) "ndulmi9"
  }
  [2]=>
  array(1) {
    [2]=>
    string(7) "jip402j"
  }
  [3]=>
  array(1) {
    [3]=>
    string(5) "3bn0d"
  }
  [4]=>
  array(1) {
    [4]=>
    string(8) "b80le1jh"
  }
  [5]=>
  array(1) {
    [5]=>
    string(5) "x31sw"
  }
  [6]=>
  array(1) {
    [6]=>
    string(8) "x8e3dge7"
  }
  [7]=>
  array(1) {
    [7]=>
    string(8) "vcpf997y"
  }
}

all arguments must be an array
bool(false)
1 голос
/ 16 декабря 2010

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

function new_array($original, $topKeys, $subKeys) {
    if (count($topKeys) != count($subKeys)) {
        return $original;
    }

    $newArray = array();
    foreach ($topKeys as $cTopKey) {
        $cSubKeys = array_shift($subKeys);

        if (array_key_exists($cTopKey, $original)) {
            $newArray[$cTopKey] = array();
            foreach ($cSubKeys as $cSubKey) {
                if (array_key_exists($cSubKey, $original[$cTopKey])) {
                    $newArray[$cTopKey][$cSubKey] = $original[$cTopKey][$cSubKey];
                }
            }
        }
    }

    return $newArray;
}

Если у вас PHP v5.1 + и индексы гарантированно доступны, и по порядку, то, я думаю, вы можете сделать это проще:

function new_array($original, $topKeys, $subKeys) {
    $newArray = array_intersect_key($original, array_flip($topKeys));
    foreach ($newArray as $cKey => $cSub) {
        $cSubKeys = array_shift($subKeys);
        $newArray[$cKey] = array_intersect_key($cSub, $cSubKeys);
    }

    return $newArray;
}

Опасность в том, что я не знаю, определено ли array_intersect_key() для сохранения первоначального порядка элементов. Если нет, то необходимо будет добавить дополнительный код, чтобы сопоставить подключи с оригиналом, в идеале в любом случае подключи должны быть вложенными массивами первого параметра.

0 голосов
/ 16 декабря 2010

почему не просто

$a = array('0' => 
               array('1' => 'bbbb', 
                     '2' => 'ccccc'), 
           '2' => 
               array('0' => 'aaaa', 
                     '2' => 'cewrcc')
           );

Зачем использовать функцию, чтобы сделать то же самое?

...