I have a simple php array for location postcode and their name. I want compress 'code' by 'name'. This code from WooCommerce database zones.
$new_arr = [
[
'name' => 'Jambi Selatan',
'code' => '36139',
'code_name' => '36139 - Jambi Selatan'
],
[
'name' => 'Jambi Selatan',
'code' => '36137',
'code_name' => '36137 - Jambi Selatan'
],
[
'name' => 'Bagan Pete',
'code' => '36129',
'code_name' => '36129 - Bagan Pete'
],
[
'name' => 'Bagan Pete',
'code' => '36127',
'code_name' => '36127 - Bagan Pete'
]
];
I want get final result combined by 'name' and 'code' like this: i try array_unique method but not working.
Array (
[0] => Array
(
[name] => Jambi Selatan
[code] => 36139, 36137
[code_name] => 36139, 36139 - Jambi Selatan
)
[1] => Array
(
[name] => Bagan Pete
[code] => 36127, 36129
[code_name] => 36127, 36129 - Bagan Pete
)
)
I try this method, but not fix at 'code_name'
$out = array();
foreach ($new_arr as $key => $value){
if (array_key_exists($value['name'], $out)){
$out[$value['name']]['code'] .= ', '.$value['code'];
} else {
$out[$value['name']] = array(
'name' => $value['name'],
'code' => $value['code'],
'code_name' => $value['code'] . ' - ' . $value['name']
);
}
}
$out = array_values($out);
print_r($out);
You have to check duplicate name by in_array and update exist array value .If not exist insert that value to $out array .
$out = array();
foreach($new_arr as $k=>$v) {
//empty array state
if(count($out) == 0) {
$out[] = $v;
continue;
}
foreach ($out as $key => $value) {
if(in_array($v["name"],$value)) {
$out[$key]["code"] .= ",".$v["code"];
//for the code_name output as OP described
$nn = explode("-", $value["code_name"]);
$l = count($nn) - 1;
unset($nn[$l]);
$out[$key]["code_name"] = implode($nn).",".$v["code_name"];
break;
} else {
if((count($out)-1) == $key) {
$out[] = $v;
}
}
}
}
var_dump($out);
For someone have problem like me, this method for fix it:
$out = array();
foreach ($new_arr as $key => $value){
if (array_key_exists($value['name'], $out)){
$out[$value['name']]['code'] .= ', '.$value['code'];
$out[$value['name']]['code_name'] .= ', '.$value['code'] . ' - ' . $value['name'];
} else {
$out[$value['name']] = array(
'name' => $value['name'],
'code' => $value['code'],
'code_name' => $value['code']
);
}
}
$out = array_values($out);
print_r($out);
Final result;
Array
(
[0] => Array
(
[name] => Jambi Selatan
[code] => 36139, 36137
[code_name] => 36139, 36137 - Jambi Selatan
)
[1] => Array
(
[name] => Bagan Pete
[code] => 36129, 36127
[code_name] => 36129, 36127 - Bagan Pete
)
)
Please try below one as another approach:
<?php
$arr = Array (
Array
(
'name' => 'Jambi Selatan',
'code' => '36139',
'code_name' => '36139 - Jambi Selatan'
),
Array
(
'name' => 'Jambi Selatan',
'code' => '36137',
'code_name' => '36137 - Jambi Selatan'
),
Array
(
'name' => 'Bagan Pete',
'code' => '36129',
'code_name' => '36129 - Bagan Pete'
),
Array
(
'name' => 'Bagan Pete',
'code' => '36127',
'code_name' => '36127 - Bagan Pete'
)
);
$newarr = array();
$finalArr = array();
foreach($arr as $aa) {
$newarr[$aa['name']][] = $aa;
}
foreach($newarr as $kk => $bb) {
foreach($bb as $cc) {
$finalArr[$kk]['name'] = $cc['name'];
if(isset($finalArr[$kk]['code'])) {
$finalArr[$kk]['code'] = $finalArr[$kk]['code'].','.$cc['code'];
} else {
$finalArr[$kk]['code'] = $cc['code'];
}
if(isset($finalArr[$kk]['code_name'])) {
$finalArr[$kk]['code_name'] = $finalArr[$kk]['code_name'].','.$cc['code_name'];
} else {
$finalArr[$kk]['code_name'] = $cc['code_name'];
}
}
}
echo "<pre>";
print_r($finalArr);
echo "</pre>";
?>
Definitely avoid any suggestions that use more than one loop to group and concatenate the data.
I do endorse #Opsional's snippet. An alternative approach is to push reference variables into the result array, then only concatenate comma-separated values to the appropriate reference variable.
Code: (Demo)
$result = [];
foreach ($arr as $row) {
if (!isset($ref[$row['name']])) {
$ref[$row['name']] = $row;
$result[] = &$ref[$row['name']];
} else {
$ref[$row['name']]['code'] .= ', ' . $row['code'];
$ref[$row['name']]['code_name'] .= ', ' . $row['code_name'];
}
}
var_export($result);
For any purist developers that insist on destroying references, call unset($ref) after the loop.
Here is a streamlined version of #Opsional's snippet: (Demo)
$result = [];
foreach ($arr as $row) {
if (!isset($result[$row['name']])) {
$result[$row['name']] = $row;
} else {
$result[$row['name']]['code'] .= ', ' . $row['code'];
$result[$row['name']]['code_name'] .= ', ' . $row['code_name'];
}
}
var_export(array_values($result));
Related
I have a result set from a query that gives me an object that has dozens of fields, the below example is a subset:
[79] => stdClass Object
(
[name] => John Doe
[email] => john#doe.com
[ext] => 4004
[options] => stdClass Object
(
[type] => friend
[rating] => Excellent
[context] => default
)
[address] => 123 Anywhere St
)
Instead of plowing through each field, because I only want a handful of them, I am trying to use an array to get what i want:
$fields = array('name','email','options->type','options->rating','address');
so then i do:
foreach ($result as $k => $v){
foreach ($fields as $kk => $vv){
echo $kk. " - " . $v->$kk."<br>";
}
}
Which gives me field name and its value.
name - John Doe
email - john#doe.com
address - 123 Anywhere St.
However, anything in that sub object(options) is giving me a blank result.
You can use a recursive function providing that you don't mind changing the format of your $fields var to include arrays. In my opinion this makes it easier to read anyway, and easier to handle in code.
The benefit of using a recursive function is that it will handle any depth.
$o = (object) [
'name' => 'John Doe',
'email' => 'john#doe.com',
'ext' => 4004,
'options' => (object) [
'type' => 'friend',
'rating' => 'Excellent',
'context' => 'default',
'any' => (object) [
'depth' => (object) [
'will' => 'work'
]
]
],
'address' => '123 Anywhere St'
];
$fields = [
'name',
'email',
'options' => [
'type',
'rating',
'any' => [
'depth' => [
'will'
]
]
],
'address'
];
function getObjectProps($o, $fields, $parent = '') {
if (strlen($parent)) {
$parent .= '->';
}
foreach ($fields as $k => $v) {
if (is_array($v)) {
getObjectProps($o->{$k}, $v, $parent . $k);
} else {
echo $parent . $v . ' - ' . $o->{$v} . '<br/>';
}
}
}
getObjectProps($o, $fields);
Output:
name - John Doe
email - john#doe.com
options->type - friend
options->rating - Excellent
options->any->depth->will - work
address - 123 Anywhere St
Use a multidimensionnal array for $fields and change your foreach loop a little bit:
$fields = [
'name',
'email',
'options' => [
'type',
'rating'
],
'address'
];
foreach ($result as $obj) {
foreach ($fields as $k => $v) {
if (is_array($v)) {
foreach ($v as $vv) {
echo $vv . ' - ' . $obj->$k->$vv . '<br>';
}
} else {
echo $v . ' - ' . $obj->$v . '<br>';
}
}
}
Here's what I came up with in the meantime
$someObject = new stdClass();
$someObject->name = 'Dale';
$someObject->options = new stdClass();
$someObject->options->address = 'The Address';
$fields = ['name', 'options' => ['address']];
function toArray($object, $fields) {
$return = [];
foreach($fields as $fieldKey => $fieldValue) {
if(!is_array($fieldValue)) {
$return [] = $object->$fieldValue;
}
else
{
$return = array_merge($return, toArray($object->$fieldKey, $fieldValue));
}
}
return $return;
}
print_r(toArray($someObject, $fields));
Try this code:
$newResult = array_intersect_key((array)$result, array_flip($fields));
There is no easy way to access property like the way you are trying. But there's a symfony's property access component which you can use. But if you are focusing to use your own method then you might love the following code. I ran this code in PHP 7.2
$data = (object) [
'name' => 'John Doe',
'email' => 'john#doe.com',
'ext' => 4004,
'options' => (object) [
'type' => "friend",
'rating' => 'Excellent',
'context' => 'default'
],
'address' => '123 Anywhere St'
];
$fields = array('name','email','options->type','options->rating','address');
/*** way of initializing
$response = []; // get array value here
$response = ""; // get string value here
***/
$response = ""; //string value here... as output
/*** Don't you think that the below code now is clean and reusable? ***/
array_map(function($key) use($data, &$response) {
$value = array_reduce(explode('->', $key), function ($o, $p) {
return $o->$p;
}, $data);
is_array($response) ? ($response[$key] = $value) : ($response .= $key . ' - ' . $value . '<br>');
}, $fields);
echo $response;
In the above code if you initialize $response as an empty array then you'll get array as output. And if you initialize that as an empty string then you'll get string output. And I think instead of using for loop, use array_map and array_reduce, they work like magic and reduce your code too.
String as output:
Array as ouput:
I have a very simple multidimensional array and some PHP code. The code should print the p_id values, but it does not do it. Do I really have to add one foreach more or is there other ways?
And here is the array:
Array (
[2764] => Array (
[status] => 0
[0] => Array (
[p_id] => 2895
)
[1] => Array (
[p_id] => 1468
)
)
[5974] => Array (
[status] => 0
[0] => Array (
[p_id] => 145
)
[1] => Array (
[p_id] => 756
)
)
)
Here is my PHP code:
foreach($arr as $innerArray)
foreach($innerArray as $key => $value)
echo $key . "=>" . $value . "<br>";
It prints:
status=>0
0=>Array
1=>Array
status=>0
0=>Array
1=>Array
foreach($arr as $a => $a_value)
{
echo $a . '<br>';
foreach($a_value as $av_arr => $av)
{
if(!is_array($av))
{
echo $av_arr . '=>' . $av . '<br>';
}
else
{
foreach($av as $inner_av => $inner_av_val)
{
echo $inner_av . '=>' . $inner_av_val . '<br>';
}
}
}
}
This simple call to array_walk_recursive() produces the output requested in the question:
array_walk_recursive(
$arr,
function ($value, $key) {
echo $key . "=>" . $value . "<br>";
}
);
But it doesn't make much sense as the output mixes the values of status with the values of p_id.
I would go for a more structured display using the original code with a little more meaning for the names of the variables:
foreach ($arr as $catId => $catInfo) {
// Category ID and details; use other names if I'm wrong
printf("Category: %d (status: %s)\n", $catId, $catInfo['status'] ? 'active' : 'inactive');
foreach ($catInfo as $key => $value) {
if ($key == 'status') {
// Ignore the status; it was already displayed
continue;
}
foreach ($value as $prodInfo) {
printf(" Product ID: %d\n", $prodInfo['p_id']);
}
}
}
The structure of the input array tells me you should first fix the code that generates it. It should group all the products (the values that are now indexed by numeric keys) into a single array. It should look like this:
$input = array(
'2764' => array(
'status' => 0,
'products' => array(
2895 => array(
'p_id' => 2895,
'name' => 'product #1',
// more product details here, if needd
),
1468 => array(
'p_id' => 1468,
'name' => 'product #2',
),
// more products here
),
// more categories here
),
Then the code that prints it will look like this:
foreach ($arr as $catId => $catInfo) {
// Category ID and details; use other names if I'm wrong
printf("Category: %d (status: %s)\n", $catId, $catInfo['status'] ? 'active' : 'inactive');
foreach ($catInfo['products'] as $prodInfo) {
printf(" %s (ID: %d)\n", $prodInfo['name'], $prodInfo['p_id']);
// etc.
}
}
Use a recursive function:
function printIds($arr) {
foreach ($arr as $key => $val) {
if (is_array($val) && array_key_exists("p_id", $val)) {
echo $val["p_id"]."\n";
} elseif(is_array($val)) {
printIds($val);
}
}
}
Working example:
$arr = [
2764 => [
'status' => 0,
['p_id' => 100],
],
4544 => [
'status' => 0,
['p_id' => 100],
],
['p_id' => 100],
];
function printIds($arr) {
foreach ($arr as $key => $val) {
if (is_array($val) && array_key_exists("p_id", $val)) {
echo $val["p_id"]"\n";
} elseif(is_array($val)) {
printIds($val);
}
}
}
printIds($arr);
The function loops all entries of a given array and echo's them out, if they contain an array with a key named "p_id". If it does find a nested array, then it does loop also all child arrays.
I've spent a while trying to get what I need from old answers but haven't quite got it (have got close though!).
I have this;
[January] => Array
(
[Tuesday] => Array
(
[foo] => Array
(
[82] => 47731
[125] => 19894
)
[bar] => Array
(
[82] => 29911
[125] => 10686
)
)
}
...and I want this;
[0] => Array
(
'key' => 'January'
'children' => Array
[0] => Array
{
'key' => 'Tuesday'
'children' => Array
[0] => Array
{
'key' => 'foo'
'values' => Array
{
[82] => 47731
[125] => 19894
}
[1] => Array
{
'key' => 'bar'
'values' => Array
{
[82] => 29911
[125] => 10686
}
}
)
}
I've got fairly close by adapting the first answer from Recursively change keys in array but only the bottom layer of my result is correct - the nodes with keys 'Tuesday', 'foo' and 'bar' just look the same as in the source array.
Here's what I've got so far;
public function transform_hierarchical_output(&$var)
{
if (is_array($var))
{
$final = [];
$i = 0;
foreach ($var as $k => &$v)
{
$new_node = [
'key' => $k,
'children' => $v
];
$k = $i;
$this->transform_hierarchical_output($v);
$final[$k] = $new_node;
$i++;
}
$var = $final;
}
elseif (is_string($var))
{
}
}
This needs to work with a source array of any length and depth.
Thanks in advance.
Geoff
<?php
$array = [
'January' => [
'Tuesday' => [
'foo' => [
82 => 47731,
125 => 19894,
],
'bar' => [
82 => 47731,
125 => 19894,
]
]
]
];
function transform(array $input)
{
$output = [];
foreach ($input as $key => $val) {
if (is_array(array_values($val)[0])) { // if next depth is an array
$output[] = [
'key' => $key,
'children' => transform($val)
];
} else {
$output[] = [
'key' => $key,
'values' => $val
];
}
}
return $output;
}
print_r(transform($array));
try below:
function t($arr)
{
$a = [];
$num = 0;
foreach($arr as $k => $v) {
if (is_array($v))
{
$a[$num] = [
'key' => $k,
];
$a[$num][is_array(array_values($v)[0]) ? 'children' : 'values'] = t($v);
$num ++;
} else {
$a[$k] = $v;
}
}
return $a;
}
First thing I should note is that, though there are many recursions in your example, but technically it is not a recursive loop in terms of the need for a self-executing function. Because your loop's scheme fluctuates a bit in its depth, it does not follow a regular pattern down to is last node; however it is a logical scheme, but is not repeated down to is last node.
The following function might work for you:
function doArray($array)
{
$keys = array_keys($array);
$arr_count = count($keys);
$new_array;
for($i = 0; $i < $arr_count; $i++)
{
$new_array[$i]["key"] = $keys[$i];
$new_keys = array_keys($array[$keys[$i]]);
for($w = 0; $w < count($new_keys); $w++)
{
$new_array[$i]["children"][$w]["keys"] = $new_keys[$i];
$new_array[$i]["children"][$w]["children"] = array();
for($w = 0; $w < count($new_keys); $w++)
{
$new_new_keys = array_keys($array[$keys[$i]][$new_keys[$w]]);
for($q = 0; $q < count($new_new_keys); $q++)
{
$new_array[$i]["children"][$w]["children"][$q]["key"] = $new_new_keys[$q];
//$new_array[$i]["children"][$w]["children"][$q]["children"] = $array[$keys[$i]][$new_keys[$w]][$new_new_keys[$q]];
$last_new_keys = array_keys($array[$keys[$i]][$new_keys[$w]][$new_new_keys[$q]]);
for($s = 0; $s < count($last_new_keys); $s++)
{
$new_array[$i]["children"][$w]["children"][$q]["values"][$last_new_keys[$s]] = $array[$keys[$i]][$new_keys[$w]][$new_new_keys[$q]][$last_new_keys[$s]];
}
}
}
}
}
return $new_array;
}
I have a multidimensional array in the following format:
$array = array (
0 =>
array (
'date' => '2013-03-25',
'name' => 'Bob',
'time' => '11'
),
1 =>
array (
'date' => '2013-03-25',
'name' => 'Brian',
'time' => '13'
),
2 =>
array (
'date' => '2013-03-26',
'name' => 'Jack',
'time' => '14'
),
3 =>
array (
'date' => '2013-03-26',
'name' => 'Bob',
'time' => '14'
)
);
I am trying to get the names and corresponding times for each date. I have got the names using the following method:
$array2 = array();
foreach($array as $item) {
$array2[$item['date']][] = $item['name'];
}
and then using:
foreach($array2[$date] as $name)
to run a query on the names returned. But I am not sure how to get the corresponding 'time' key for each 'name' key in the second foreach loop.
Why you don't want to store both name and time for each date key?
$array2 = array();
foreach ($array as $item) {
$array2[$item['date']] []= array($item['time'], $item['name']);
}
You can reach name and time with this code:
foreach ($array2 as $row) {
$name = $row[0];
$time = $row[1];
}
You can try
$list = array();
foreach ( $array as $k => $item ) {
$list[$item['date']][] = array(
$item['name'],
$item['time']
);
}
foreach ( $list as $date => $data ) {
echo $date, PHP_EOL;
foreach ( $data as $var ) {
list($name, $time) = $var;
echo $name, " ", $time, PHP_EOL;
}
echo PHP_EOL;
}
Output
2013-03-25
Bob 11
Brian 13
2013-03-26
Jack 14
Bob 14
try the following:
foreach($array as $item) {
$array2[$item['date'][] = array('name' => $item['name'], 'time' => $item['time']);
}
foreach($array2[$date] as $name) {
echo $name['name'] . ' => ' . $name['time'] . "\n";
}
I'm in PHP and I've got an array that looks like this. A single dimension array whose keys are bracketed strings.
array(
'matrix[min_rows]' => '0',
'matrix[max_rows]' => '',
'matrix[col_order][]' => 'col_new_1',
'matrix[cols][col_new_0][type]' => 'text',
'matrix[cols][col_new_1][type]' => 'text',
'matrix[cols][col_new_0][label]' => 'Cell 1',
'matrix[cols][col_new_1][label]' => 'Cell 2',
'matrix[cols][col_new_0][name]' => 'cell_1',
'matrix[cols][col_new_1][name]' => 'cell_2',
'matrix[cols][col_new_0][instructions]' => '',
'matrix[cols][col_new_1][instructions]' => '',
'matrix[cols][col_new_0][width]' => '33%',
'matrix[cols][col_new_1][width]' => '',
'matrix[cols][col_new_0][settings][maxl]' => '',
'matrix[cols][col_new_0][settings][fmt]' => 'none',
'matrix[cols][col_new_0][settings][content]' => 'all',
'matrix[cols][col_new_1][settings][maxl]' => '140',
'matrix[cols][col_new_1][settings][multiline]' => 'y',
'matrix[cols][col_new_1][settings][fmt]' => 'none',
'matrix[cols][col_new_1][settings][content]' => 'all',
)
Is there any easy way to convert that to a normal nested array, ie:
array(
'matrix' => array(
'min_rows' => '0',
'max_rows' => '',
'col_order' => array('col_new_1'),
'cols' => array(
'col_new_0' => array(
'type' => 'text',
'label' => 'Cell 1',
....etc....
This is my current solution, but I was wondering if there's something more native or efficient:
foreach ($decoded_field_type_settings as $key => $value)
{
if (preg_match_all('/\[(.*?)\]/', $key, $matches))
{
$new_key = substr($key, 0, strpos($key, '['));
if ( ! isset($field_type_settings[$new_key]))
{
$field_type_settings[$new_key] = array();
}
$array =& $field_type_settings[$new_key];
$count = count($matches[1]) - 1;
foreach ($matches[1] as $i => $sub_key)
{
if ( ! $sub_key)
{
if ($i < $count)
{
$array[] = array();
}
else
{
$array[] = $value;
}
}
else
{
if ( ! isset($array[$sub_key]))
{
if ($i < $count)
{
$array[$sub_key] = array();
}
else
{
$array[$sub_key] = $value;
}
}
}
if ($i < $count)
{
$array =& $array[$sub_key];
}
}
}
else
{
$field_type_settings[$key] = $value;
}
}
UPDATE: I posted an answer below.
This might work, although it would probably generate some warnings:
$matrix = array();
foreach($arr as $key => $value) {
eval('$' . $key . ' = \'' . $value . '\';');
}
var_dump($matrix);
I think this should do it...
<?php
function convert2dTo3d($source) {
$refs = array();
$output = array();
foreach ($source AS $key => $val) {
$tok = strtok($key, '[]');
$prev_tok = NULL;
while ($tok !== FALSE) {
$this_ref =& $refs[$tok];
if ($prev_tok === NULL)
$output[$tok] =& $this_ref;
else
$refs[$prev_tok][$tok] =& $this_ref;
$prev_tok = $tok;
$tok = strtok('[]');
if ($tok === FALSE)
$refs[$prev_tok] = $val;
}
}
return $output;
}
// Test
$source = array(
'matrix[min_rows]' => '0',
'matrix[max_rows]' => '',
'matrix[col_order][]' => 'col_new_1',
'matrix[cols][col_new_0][type]' => 'text',
'matrix[cols][col_new_1][type]' => 'text',
'matrix[cols][col_new_0][label]' => 'Cell 1',
'matrix[cols][col_new_1][label]' => 'Cell 2',
'matrix[cols][col_new_0][name]' => 'cell_1',
'matrix[cols][col_new_1][name]' => 'cell_2',
'matrix[cols][col_new_0][instructions]' => '',
'matrix[cols][col_new_1][instructions]' => '',
'matrix[cols][col_new_0][width]' => '33%',
'matrix[cols][col_new_1][width]' => '',
'matrix[cols][col_new_0][settings][maxl]' => '',
'matrix[cols][col_new_0][settings][fmt]' => 'none',
'matrix[cols][col_new_0][settings][content]' => 'all',
'matrix[cols][col_new_1][settings][maxl]' => '140',
'matrix[cols][col_new_1][settings][multiline]' => 'y',
'matrix[cols][col_new_1][settings][fmt]' => 'none',
'matrix[cols][col_new_1][settings][content]' => 'all',
);
echo "<pre>";
print_r(convert2dTo3d($source));
echo "</pre>";
It seems that the OP wants, as output, an array declaration which can be parsed directly by PHP. So I suggest to use var_export().
$array = array(
'matrix[min_rows]' => '0',
// ......
// ......
// ......
'matrix[cols][col_new_1][settings][content]' => 'all'
);
$matrix = array();
foreach ($array as $key => $value)
{
// fix missing quotes around array indexes
$key = str_replace(array("[", "]", "['']"), array("['", "']", "[]"), $key);
// fill PHP array
eval('$'.$key.' = $value;');
}
var_export($matrix);
You can make use of a simple, regular expression based parser that creates a multidimensional array based on the information stored in the string per each key:
function parse_flat_matrix(array $flat)
{
$matrix = array();
$varname = 'matrix';
$nameToken = '[a-z0-9_]*';
foreach($flat as $key => $value)
{
$keys = preg_split(sprintf('/(\[%s\])/', $nameToken), $key, 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
if ($varname !== array_shift($keys))
{
throw new InvalidArgumentException(sprintf('Invalid key %s.', $key));
}
$p =& $matrix;
foreach($keys as $k)
{
$r = preg_match(sprintf('/^\[(%s)\]$/', $nameToken), $k, $kk);
if (!$r)
{
throw new InvalidArgumentException(sprintf('Invalid subkey %s in key %s.', $k, $key));
}
if ('' === $kk[1])
{
$p =& $p[];
}
else
{
$p =& $p[$kk[1]];
}
}
$p = $value;
unset($p);
}
return $matrix;
}
With your example data given, it will create this array:
Array
(
[min_rows] => 0
[max_rows] =>
[col_order] => Array
(
[0] => col_new_1
)
[cols] => Array
(
[col_new_0] => Array
(
[type] => text
[label] => Cell 1
[name] => cell_1
[instructions] =>
[width] => 33%
[settings] => Array
(
[maxl] =>
[fmt] => none
[content] => all
)
)
[col_new_1] => Array
(
[type] => text
[label] => Cell 2
[name] => cell_2
[instructions] =>
[width] =>
[settings] => Array
(
[maxl] => 140
[multiline] => y
[fmt] => none
[content] => all
)
)
)
)
This was the simplest solution, involving no regex parsing:
$original_array = array(
'matrix[min_rows]' => '0',
'matrix[max_rows]' => '',
'matrix[col_order][]' => 'col_new_1',
'matrix[cols][col_new_0][type]' => 'text',
'matrix[cols][col_new_1][type]' => 'text',
'matrix[cols][col_new_0][label]' => 'Cell 1',
'matrix[cols][col_new_1][label]' => 'Cell 2',
'matrix[cols][col_new_0][name]' => 'cell_1',
'matrix[cols][col_new_1][name]' => 'cell_2',
'matrix[cols][col_new_0][instructions]' => '',
'matrix[cols][col_new_1][instructions]' => '',
'matrix[cols][col_new_0][width]' => '33%',
'matrix[cols][col_new_1][width]' => '',
'matrix[cols][col_new_0][settings][maxl]' => '',
'matrix[cols][col_new_0][settings][fmt]' => 'none',
'matrix[cols][col_new_0][settings][content]' => 'all',
'matrix[cols][col_new_1][settings][maxl]' => '140',
'matrix[cols][col_new_1][settings][multiline]' => 'y',
'matrix[cols][col_new_1][settings][fmt]' => 'none',
'matrix[cols][col_new_1][settings][content]' => 'all',
);
$query_string = http_build_query($original_array);
$final_array = array();
parse_str($query_string, $final_array);
var_dump($final_array);