Вот 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' => '...'),
),
),
)
Стопа - спасибо! Прекрасно работает. Так же, как вы указали, отлично с ключом attr, который нужно сохранить. Большое спасибо! – chrney
Добро пожаловать, рад, что вам понравилось. – trincot
Извините, что беспокою вас еще раз. Я понял, что бывают случаи, когда в начале массива нет ни одного класса «listen-to». Вместо этого массив начинается с таких вещей: Array ('attr' => Array(), 'content' => '...'), Array ('attr' => Array ('class' => ' все '),' content '=>' ... '), Array (' attr '=> Array (' class '=>' anything '),' content '=>' ... '), Array ('attr' => Array(), 'content' => '...'), Не могли бы вы мне помочь, чтобы получить это в блоке, отметив атрибут type как «pre» и с нулевым как ценность контента? – chrney