I'm not sure how to work the title of this question, so sorry if it's a little confusing.
I have an array;
Array
(
[username] => Array
(
[0] => 'a'
[1] => 'b'
[2] => 'c'
[3] => 'd'
[4] => 'e'
[5] => 'f'
)
[email] => Array
(
[0] =>
[1] =>
[2] =>
[3] =>
[4] =>
[5] =>
)
[level] => Array
(
[0] => 1
[1] => 1
[2] => 1
[3] => 1
[4] => 1
[5] => 1
)
[role] => Array
(
[0] => 2
[1] => 1
[2] => 1
[3] => 1
[4] => 2
[5] => 1
)
[password] => Array
(
[0] =>
[1] =>
[2] =>
[3] =>
[4] =>
[5] =>
)
[id] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
)
)
But I want it in this format:
Array
(
[0] => Array
(
[username] => 'a'
[id] => 'a'
[email] => 'a'
)
[1] => Array
(
[username] => 'a'
[id] => 'a'
[email] => 'a'
)
[2] => Array
(
[username] => 'a'
[id] => 'a'
[email] => 'a'
)
[3] => Array
(
[username] => 'a'
[id] => 'a'
[email] => 'a'
)
[4] => Array
(
[username] => 'a'
[id] => 'a'
[email] => 'a'
)
[5] => Array
(
[username] => 'a'
[id] => 'a'
[email] => 'a'
)
I can't seem to figure it out, arrays end too soon, or there ends up being too many indexes etc. Ideas?
I would loop through the array and reconstruct it like so:
$index_count = count($array['username']); // in your case, this is 6
$new_array = array();
for ($i = 0; $i < $index_count; $i++) {
$new_array[] = array(
'username' => $array['username'][$i],
'email' => $array['email'][$i],
'id' => $array['id'][$i]
);
}
UPDATE If you want this to take into consideration any and all possible keys, try this:
$keys = array_keys($array);
if (count($keys)) {
$index_count = count($array[$keys[0]]);
$myArray = array();
for ($i = 0; $i < $index_count; $i++) {
$temp = array();
foreach($keys as $key) {
$temp[$key] = $array[$key][$i];
}
$myArray[] = $temp;
}
}
A different take, but here's what I would do - step by step:
First, let's get the keys - we'll be needing them a lot:
$result = array();//<-- this is the result array
$keys = array_keys($array);
Then, I'd get an empty, template array (somewhat like a model object)
$base = array_fill_keys($keys,array());
//array('username'=>array,'id'=>array(),...
Then, use that to build your result array:
$result = array_fill(0,count($array['username']),$base);
//In one-liner format, it looks like this:
$result = array_fill(0,count($array['username']),array_fill_keys(array_keys($array),array()));
//Works, but is messy as f***
Then just fill the lot, this is where that $keys
variable pays off:
$length = count($result);
while ($key = array_shift($keys))
{
for ($i=0;$i<$length;$i++)
{
$result[$i][$key] = $array[$key][$i];
}
}
Note that I prefer using a while loop, as it is cleaner and (marginally) faster. Cleaner because that $keys
array is being emptied as you go along. If you're working with substantial amounts of data it can sometimes make a difference. If the dataset is REALLY large, and the code has been thoroughly tested, you might even want to consider shifting
from the source array (as it contains all data, it's a lot bigger than a an array containing just the keys):
while ($vals = array_shift($array))
{
$key = array_shift($keys);//<-- keep track of what array has been shifted
for ($i=0;$i<$length;$i++)
{
$result[$i][$key] = $vals[$i];
}
}
This neatly cleans up the source array, and the keys. I've tested this last approach on my server, writecodeonline and codepad, all with exactly the same results:
$foo = array('bar'=>array_fill(0,2,'ás'),'quar'=>range('a','z'));
$keys = array_keys($foo);
while($vals = array_shift($foo))
{
$key = array_shift($keys);
echo $key.' contains: => '.implode(', ',$vals).'<br/>';
}
bar contains: => ás, ás
quar contains: => a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z