PHPFilter: Need to sort array in a weird way - help
January 24, 2013 8:36 AM Subscribe
I have an array which has listing information for products on a website. The products fit into two categories (call them 'bits' and 'bobs') I need to sort the array so that it goes from a completely mixed up and randomized list to:
bit, bit, bit, bit, bit, bit, bob, bob, bob, bob, bob, bob, bit, bit, bit, bit, bit, bit
And so on, basically reorganize the array so that the list is in alternating groups of six
Array structure is basically a numbered array of keyed arrays, like so:
Array
(
[0] => Array
(
[id] => 39549
[title] => Product Name
[author] => Author Name
[price] => 7.66
[type] => bit
)
[1] => Array
(
[id] => 39549
[title] => Product Name
[author] => Author Name
[price] => 9.66
[type] => bob
)
)
Bug - position and current should be the same variable.
posted by Nothing at 8:57 AM on January 24, 2013
posted by Nothing at 8:57 AM on January 24, 2013
Nothing beat me to it but here's my solution (since I wrote it anyway lol)
$bitIndex=$bobIndex=0;
$bits= $bobs = array();
foreach($categories as $c)
{
$arr = &${$c['type'].'s'};
$i = &${$c['type'].'Index'};
$arr[$i][]=$c;
if(count($arr[$i])==6)
{
$i++;
}
}
$max = count($bobs)>count($bits)?count($bobs):count($bits);
$sorted = array();
for($i=0;$i<> {
$sorted = array_merge($sorted,$bits[$i]?$bits[$i]:array(),$bobs[$i]?$bobs[$i]:array());
}>
posted by missmagenta at 9:05 AM on January 24, 2013
$bitIndex=$bobIndex=0;
$bits= $bobs = array();
foreach($categories as $c)
{
$arr = &${$c['type'].'s'};
$i = &${$c['type'].'Index'};
$arr[$i][]=$c;
if(count($arr[$i])==6)
{
$i++;
}
}
$max = count($bobs)>count($bits)?count($bobs):count($bits);
$sorted = array();
for($i=0;$i<> {
$sorted = array_merge($sorted,$bits[$i]?$bits[$i]:array(),$bobs[$i]?$bobs[$i]:array());
}>
posted by missmagenta at 9:05 AM on January 24, 2013
Response by poster: I understand nothing's code, more or less but PHP calls the += for output an illegal operator. I tried to substitute array_merge but it calls the results of array_slice "not an array" so that doesn't work. Not sure why. Looks like it should to me.
missmagenta, I tried your code (which I find hard to understand) but I'm not sure how to change what your script is looking for to what is actually in the array. I should maybe have been more clear but the array 'type' is actually called 'smartphoneflag' and is either a 1 or a 0.
Help...!
posted by signsofrain at 10:23 AM on January 24, 2013
missmagenta, I tried your code (which I find hard to understand) but I'm not sure how to change what your script is looking for to what is actually in the array. I should maybe have been more clear but the array 'type' is actually called 'smartphoneflag' and is either a 1 or a 0.
Help...!
posted by signsofrain at 10:23 AM on January 24, 2013
Changed it slightly
$indexes=array(0,0);
$bitsandbobs = array();
foreach($categories as $c)
{
$bitsandbobs[$c['smartphoneflag']][$indexes[$c['smartphoneflag']]][]=$c;
if(count($bitsandbobs[$c['smartphoneflag']][$indexes[$c['smartphoneflag']]])==6)
{
$indexes[$c['smartphoneflag']]++;
}
}
$bits = $bitsandbobs[0];
$bobs = $bitsandbobs[1];
$max = count($bobs)>count($bits)?count($bobs):count($bits);
$sorted = array();
for($i=0;$i<> {
$sorted = array_merge($sorted,$bits[$i]?$bits[$i]:array(),$bobs[$i]?$bobs[$i]:array());
}
Basically it sorts through the array of categories and separates the bits and bobs into arrays of 6 items. The array $bitsandbobs has the "bits" arrays at index 0 and the "bobs" at 1 so you can use the 0/1 smartphoneflag to put them in the right place, then you have indexes which is the same (bits in 0 and bobs in 1) so the relevant index is incremented when the current array reaches 6 items.
(sorry, I suck at explanations, hope this helps)>
posted by missmagenta at 11:27 AM on January 24, 2013
$indexes=array(0,0);
$bitsandbobs = array();
foreach($categories as $c)
{
$bitsandbobs[$c['smartphoneflag']][$indexes[$c['smartphoneflag']]][]=$c;
if(count($bitsandbobs[$c['smartphoneflag']][$indexes[$c['smartphoneflag']]])==6)
{
$indexes[$c['smartphoneflag']]++;
}
}
$bits = $bitsandbobs[0];
$bobs = $bitsandbobs[1];
$max = count($bobs)>count($bits)?count($bobs):count($bits);
$sorted = array();
for($i=0;$i<> {
$sorted = array_merge($sorted,$bits[$i]?$bits[$i]:array(),$bobs[$i]?$bobs[$i]:array());
}
Basically it sorts through the array of categories and separates the bits and bobs into arrays of 6 items. The array $bitsandbobs has the "bits" arrays at index 0 and the "bobs" at 1 so you can use the 0/1 smartphoneflag to put them in the right place, then you have indexes which is the same (bits in 0 and bobs in 1) so the relevant index is incremented when the current array reaches 6 items.
(sorry, I suck at explanations, hope this helps)>
posted by missmagenta at 11:27 AM on January 24, 2013
Response by poster: I'm probably just not as advanced a coder as you. While I understand your explanation, that actual code is unreadable to me, so I don't think I can debug it. In any case, when I paste it in the parser just chokes. I have error reporting turned on and normally when the script is broken I can see why on the webpage in question... but this time it's like... nothing. None of the PHP in the file in question is executed (it's included in another file)
Thanks for your efforts thus far!
posted by signsofrain at 11:49 AM on January 24, 2013
Thanks for your efforts thus far!
posted by signsofrain at 11:49 AM on January 24, 2013
Response by poster: Tried putting the code by itself into a file and executing it on the command-line. PHP says:
PHP Parse error: syntax error, unexpected '{' in /var/www/quickseries/test.php on line 17
Looks like that's around the 'for'
posted by signsofrain at 11:55 AM on January 24, 2013
PHP Parse error: syntax error, unexpected '{' in /var/www/quickseries/test.php on line 17
Looks like that's around the 'for'
posted by signsofrain at 11:55 AM on January 24, 2013
Best answer: ah, I see the problem, its gotten a little mangled in the posting.
posted by missmagenta at 11:57 AM on January 24, 2013
$indexes=array(0,0);
$bitsandbobs = array();
foreach($categories as $c)
{
$bitsandbobs[$c['smartphoneflag']][$indexes[$c['smartphoneflag']]][]=$c;
if(count($bitsandbobs[$c['smartphoneflag']][$indexes[$c['smartphoneflag']]])==6)
{
$indexes[$c['smartphoneflag']]++;
}
}
$bits = $bitsandbobs[0];
$bobs = $bitsandbobs[1];
$max = count($bobs)>count($bits)?count($bobs):count($bits);
$sorted = array();
for($i=0;$i<$max;$i++)
{
$sorted = array_merge($sorted,$bits[$i]?$bits[$i]:array(),$bobs[$i]?$bobs[$i]:array());
}
posted by missmagenta at 11:57 AM on January 24, 2013
Response by poster: Thanks, that's perfect! Did just what I needed. :D
posted by signsofrain at 12:07 PM on January 24, 2013
posted by signsofrain at 12:07 PM on January 24, 2013
Yay! I can attempt to explain what it does better if you like or did you figure it out?
posted by missmagenta at 12:37 PM on January 24, 2013
posted by missmagenta at 12:37 PM on January 24, 2013
This thread is closed to new comments.
Without going into how you ended up needing this:
$bits = array_filter($array,'is_bit');
$bob = array_filter($array,'is_bob');
$total_bits = count($bits);
$total_bobs = count($bobs);
$position = 0;
$output = array();
while($position < $total_bits || $position < $total_bobs)
{
$output += array_slice($bits, $position,6);
$output += array_slice($bobs, $position,6);
$current += 6;
}
function is_bit($item)
{
return $item['type'] == 'bit';
}
function is_bob($item)
{
return $item['type'] == 'bob';
}
posted by Nothing at 8:56 AM on January 24, 2013