Reputation: 103
I have the following array called $zoo
Array
(
[0] => &dog&
[1] => *1*
[2] => one
[3] => &cat&
[4] => *2*
[5] => two
[6] => &mouse&
[7] => *3*
[8] => three
[9] => &dog&
[10] => *4*
[11] => four
)
and i need the following result:
Array
(
[&dog&] => Array
(
[0] => Array
(
[0] => *1*
[1] => one
)
[1] => Array
(
[0] => *4*
[1] => four
)
)
[&cat&] => Array
(
[0] => Array
(
[0] => *2*
[1] => two
)
)
[&mouse&] => Array
(
[0] => Array
(
[0] => *3*
[1] => three
)
)
)
This is what I have come up with but the problem is that for [&dog&] he gives me only the last value (namely 4, four) and not the first value (1, one)
$animals=array();
for ($i = 0; $i < count($zoo); $i++)
{
if($zoo[$i][0] === "&")
{
$name=$zoo[$i];
if (isset($name))
$animals[$name] = array($liste);
else
$animals[$name] = array($liste);
$liste="";
}
if($zoo[$i][0] !== "&")
{
$number = $zoo[$i];
$liste[] = $number;
$animals[$name] = array($liste);
}
}
print_r($animals);
this results in
Array
(
[&dog&] => Array
(
[0] => Array
(
[0] => *4*
[1] => four
)
)
[&cat&] => Array
(
[0] => Array
(
[0] => *2*
[1] => two
)
)
[&mouse&] => Array
(
[0] => Array
(
[0] => *3*
[1] => three
)
)
)
can anyone point me in the good direction?
Upvotes: 1
Views: 418
Reputation: 19552
A solution that works for an array that has any number of indices that should grouped. It simply searches for a &
prefix and adds the new values to the animals entry.
$zooAmp = array(
'&dog&',
'*1*',
'one',
'&cat&',
'*2*',
'two',
'&mouse&',
'*3*',
'three',
'&dog&',
'*4*',
'four'
);
$zooStar = array(
'*1*',
'&dog&',
'one',
'*2*',
'&cat&',
'two',
'*3*',
'&mouse&',
'three',
'*4*',
'&dog&',
'four'
);
function & refactor(array $unfactored) {
$len = count($unfactored);
$data = array();
if ($len<3) {
return $data;
}
if ($unfactored[0][0]=='&') {
//this algorithm isn't too bad, just loop through and add the ones starting with
//'&' to the data, and write everything from that index down to the next '&'
//into the created index in data.
$i=0;
while ($i<$len) {
if (!array_key_exists($unfactored[$i], $data))
$data[$unfactored[$i]] = array();
//save to $arr for easier reading and writing
$arr = &$data[$unfactored[$i]];
$index = count($arr);
$arr[$index] = array();
for ($c=$i+1; $c<$len && $unfactored[$c][0]!='&'; $c++) {
$arr[$index][] = $unfactored[$c];
}
$i = $c;
}
} elseif ($unfactored[0][0]=='*') {
//this algorithm is a bit harder, but not so bad since we've already done the
//basic algorithm above. We just need to store the ones with a '*' and then
//add them back into the array after it's been created.
$i=0;
$unorganizedItem = NULL;
while ($i<$len) {
$key = $unfactored[$i];
if ($key[0]=='*') {
$unorganizedItem = $key;
$i++;
} elseif ($key[0]=='&') {
if(!array_key_exists($key, $data))
$data[$key] = array();
//save to $arr for easier reading and writing
$arr = &$data[$key];
$index = count($arr);
$arr[$index][] = $unorganizedItem;
$unorganizedItem = null;
for ($c=$i+1; $c<$len && $unfactored[$c][0]!='&'; $c++) {
if ($unfactored[$c][0]=='*') {
$unorganizedItem = $unfactored[$c];
} else {
$arr[$index][] = $unfactored[$c];
}
}
$i = $c;
}
}
}
return $data;
}
print_r(refactor($zooAmp));
print_r(refactor($zooStar));
Prints:
Array
(
[&dog&] => Array
(
[0] => Array
(
[0] => *1*
[1] => one
)
[1] => Array
(
[0] => *4*
[1] => four
)
)
[&cat&] => Array
(
[0] => Array
(
[0] => *2*
[1] => two
)
)
[&mouse&] => Array
(
[0] => Array
(
[0] => *3*
[1] => three
)
)
)
Array
(
[&dog&] => Array
(
[0] => Array
(
[0] => *1*
[1] => one
)
[1] => Array
(
[0] => *4*
[1] => four
)
)
[&cat&] => Array
(
[0] => Array
(
[0] => *2*
[1] => two
)
)
[&mouse&] => Array
(
[0] => Array
(
[0] => *3*
[1] => three
)
)
)
Upvotes: 1
Reputation: 33658
$animals = array();
$c = count($zoo)/3;
for ($i = 0 ; $i < $c ; $i++)
{
$species = array_shift($zoo);
$number = array_shift($zoo);
$number_text = array_shift($zoo);
$animals[$species] []= array($number, $number_text);
}
If you want the start of a new animal be triggered by the "&" in the text, there are several solutions. Here's mine:
$animals = array();
unset($current_animal);
foreach ($zoo as $text)
{
if ($text{0} == '&')
{
// Insert an element for the new animal and get a reference to it
$animals[$text] []= array();
end($animals[$text]);
$current_animal =& $animals[$text][key($animals[$text])];
}
else
$current_animal []= $text;
}
unset($current_animal);
Upvotes: 2