2015-11-29 2 views
0

У меня есть массив как это:Массив блокировать список

0 = Array('attr' => Array('class' => 'class1'), 'content'=>'class-1-content'), 
1 = Array('attr' => Array(), 'content'=>'...'), 
2 = Array('attr' => Array('class' => 'whatever'), 'content'=>'...'), 
3 = Array('attr' => Array('class' => 'anything'), 'content'=>'...'), 
4 = Array('attr' => Array(), 'content'=>'...'), 
5 = Array('attr' => Array('class' => 'class2'), 'content'=>'...'), 
6 = Array('attr' => Array('key' => 'more-here'), 'content'=>'...'), 
7 = Array('attr' => Array('class' => 'class1'), 'content'=>'class-1-again'), 
8 = Array('attr' => Array('another-attr' => ''), 'content'=>'...'), 
9 = Array('attr' => Array(), 'content'=>'...'), 
10 = Array('attr' => Array('class' => 'and-so-on'), 'content'=>'...'), 
... 

Я хотел бы создать функциональные подбирая определенные атрибуты (как в моем случае выше всех классов равных «class1» или «class2») и группировать их до тех пор, пока что-нибудь еще не «начнет». В основном, чтобы создать такой результат:

0 = Array(type='class1', 'content='class-1-content', block=Array(
    0 = Array('attr' => Array(), 'content'=>'...'), 
    1 = Array('attr' => Array('class' => 'whatever'), 'content'=>'...'), 
    2 = Array('attr' => Array('class' => 'anything'), 'content'=>'...'), 
    3 = Array('attr' => Array(), 'content'=>'...') 
), 
1 = Array(type='class2', 'content'=>'content-class-2', block=Array( 
    0 = Array('attr' => Array('key' => 'more-here'), 'content'=>'...'), 
), 
2 = Array(type='class1', 'content'=>'class-1-again', block=Array( 
    0 = Array('attr' => Array('another-attr' => ''), 'content'=>'...'), 
    1 = Array('attr' => Array(), 'content'=>'...'), 
    2 = Array('attr' => Array('class' => 'and-so-on'), 'content'=>'...') 
) 

Может ли кто-нибудь помочь мне выяснить, как это сделать наилучшим образом? Было бы здорово создать «kick-in-list», например Array («class1», «class2», «class3») и т. Д., Чтобы создать эти блоки.

Большое спасибо!

ответ

1

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

function convert($data, $pattern) { 
    $result = array(); 
    foreach($data as $element) { 
     if (array_key_exists("attr", $element) && 
       array_key_exists("class", $element["attr"]) && 
       preg_match($pattern, $element["attr"]["class"])) { 
      $group = $element; 
      // set the "type" key/value 
      $group["type"] = $group["attr"]["class"]; 
      // remove the "class" key 
      unset($group["attr"]["class"]); 
      // remove the "attr" key, unless not empty 
      if (sizeof($group["attr"]) == 0) { 
       unset($group["attr"]); 
      } 
      // initialise "block" for collecting the next items 
      $group["block"] = array(); 
      // add the group array to the result 
      $result[] = $group; 
     } else { 
      if (!sizeof($result)) { 
       // create a "pre" group if there was not yet a group: 
       $result[] = array("type" => "pre", "content" => null, "block" => array()); 
      } 
      // add to block 
      $result[sizeof($result)-1]["block"][] = $element; 
     } 
    } 
    return $result; 
} 

// Set-up test data 
$data = Array(
    Array('attr' => Array('class' => 'class1'), 'content'=>'class-1-content'), 
    Array('attr' => Array(), 'content'=>'...'), 
    Array('attr' => Array('class' => 'whatever'), 'content'=>'...'), 
    Array('attr' => Array('class' => 'anything'), 'content'=>'...'), 
    Array('attr' => Array(), 'content'=>'...'), 
    Array('attr' => Array('class' => 'class2'), 'content'=>'class-2-content'), 
    Array('attr' => Array('key' => 'more-here'), 'content'=>'...'), 
    Array('attr' => Array('class' => 'class1'), 'content'=>'class-1-again'), 
    Array('attr' => Array('another-attr' => ''), 'content'=>'...'), 
    Array('attr' => Array(), 'content'=>'...'), 
    Array('attr' => Array('class' => 'and-so-on'), 'content'=>'...') 
); 

// Call function on test data, grouping on class1 and class2 
var_export (convert($data, "/^class[1-2]$/")); 

Выход выше сценария является:

array (
    0 => array ('content' => 'class-1-content', 'type' => 'class1', 'block' => array (
     0 => array ('attr' => array(), 'content' => '...'), 
     1 => array ('attr' => array ('class' => 'whatever'), 'content' => '...'), 
     2 => array ('attr' => array ('class' => 'anything'), 'content' => '...'), 
     3 => array ('attr' => array(), 'content' => '...'), 
     ), 
    ), 
    1 => array ('content' => 'class-2-content', 'type' => 'class2', 'block' => array (
     0 => array ('attr' => array ('key' => 'more-here'), 'content' => '...'), 
     ), 
    ), 
    2 => array ('content' => 'class-1-again', 'type' => 'class1', 'block' => array (
     0 => array ('attr' => array ('another-attr' => ''), 'content' => '...'), 
     1 => array ('attr' => array(), 'content' => '...'), 
     2 => array ('attr' => array ('class' => 'and-so-on'), 'content' => '...'), 
    ), 
), 
) 

... что то, что вы указанный как ожидаемый результат.

Существует некоторая проверка здравомыслия, чтобы избежать удаления ключа attr, если у него будет больше атрибута группы class. Это не происходит в ваших тестовых данных, но лучше быть в безопасности.

Кроме того, если данные не начинается с элемента к группе с помощью (т.е. не в class1 или class2 случае в приведенном примере), группа фиктивная «до» ставится в результате, которые будут групповые эти сиротские массивы. Пример этого:

$data = Array(
    Array('attr' => Array(), 'content'=>'...'), 
    Array('attr' => Array('class' => 'whatever'), 'content'=>'...'), 
    Array('attr' => Array('class' => 'anything'), 'content'=>'...'), 
    Array('attr' => Array(), 'content'=>'...'), 
    Array('attr' => Array('class' => 'class1'), 'content'=>'class-1-content'), 
    Array('attr' => Array(), 'content'=>'...') 
); 

будет приводить к этому выходу:

array (
    0 => array ('type' => 'pre', 'content' => NULL, 'block' => array (
     0 => array ('attr' => array(), 'content' => '...'), 
     1 => array ('attr' => array ('class' => 'whatever'), 'content' => '...'), 
     2 => array ('attr' => array ('class' => 'anything'), 'content' => '...'), 
     3 => array ('attr' => array(), 'content' => '...') 
     ), 
    ), 
    1 => array ('content' => 'class-1-content', 'type' => 'class1', 'block' => array (
     0 => array ('attr' => array(), 'content' => '...'), 
     ), 
    ), 
) 
+0

Стопа - спасибо! Прекрасно работает. Так же, как вы указали, отлично с ключом attr, который нужно сохранить. Большое спасибо! – chrney

+0

Добро пожаловать, рад, что вам понравилось. – trincot

+0

Извините, что беспокою вас еще раз. Я понял, что бывают случаи, когда в начале массива нет ни одного класса «listen-to». Вместо этого массив начинается с таких вещей: Array ('attr' => Array(), 'content' => '...'), Array ('attr' => Array ('class' => ' все '),' content '=>' ... '), Array (' attr '=> Array (' class '=>' anything '),' content '=>' ... '), Array ('attr' => Array(), 'content' => '...'), Не могли бы вы мне помочь, чтобы получить это в блоке, отметив атрибут type как «pre» и с нулевым как ценность контента? – chrney

0

Это может быть выполнено с использованием foreach() по вашему текущему массиву. Затем, если есть значение ['attr']['class'], мы проверяем его, если он начинается с class, используя strpos(). Если strpos() === 0 мы добавим его как новый элемент верхнего массива, если мы не добавим его как новый элемент вспомогательного массива к последнему элементу верхнего массива, используя простой счетчик var, т.е. $i.

$arrays = Array(
    Array('attr' => Array('class' => 'class1'), 'content'=>'class-1-content'), 
    Array('attr' => Array(), 'content'=>'...'), 
    Array('attr' => Array('class' => 'whatever'), 'content'=>'...'), 
    Array('attr' => Array('class' => 'anything'), 'content'=>'...'), 
    Array('attr' => Array(), 'content'=>'...'), 
    Array('attr' => Array('class' => 'class2'), 'content'=>'...'), 
    Array('attr' => Array('key' => 'more-here'), 'content'=>'...'), 
    Array('attr' => Array('class' => 'class1'), 'content'=>'class-1-again'), 
    Array('attr' => Array('another-attr' => ''), 'content'=>'...'), 
    Array('attr' => Array(), 'content'=>'...'), 
    Array('attr' => Array('class' => 'and-so-on'), 'content'=>'...') 
); 

$i=-1; // simple counter 
$newArray=array(); 
foreach($arrays as $array){ 
    if (isset($array['attr']['class']) && (0 === strpos($array['attr']['class'], 'class'))) { 
     $i++; // increase the counter 
     $newArray[]=$array; // add a new array element 
    } 
    else { 
     $newArray[$i]['block'][]=$array; // add a new sub array element 
    } 
} 

пример здесь - https://3v4l.org/U1V8n

Смежные вопросы