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 ) )
posted by signsofrain to Computers & Internet (10 answers total)
 
Just to be clear, you have an array of items. The items are associative arrays, having a type which can be one of two values. You need to sort the items into alternating groups of 6 based on their type.

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


Bug - position and current should be the same variable.
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


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


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


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


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


Best answer: ah, I see the problem, its gotten a little mangled in the posting.

$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


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


« Older ID Essentials - Virgin Mobile   |   Tax-dodger-fingering hypocrisy? Newer »
This thread is closed to new comments.