This function can sort a query result in some way. Maximum of 2000 rows in live and more if you cache the order.

For exemple, for album, you can have the style information like rock, pop, metal, etc... But you can also have informations like 'is a best seller', 'is new', 'is a legendary album', etc...

If you want to mix everything like a rock album which is a best seller first, and pop album which is new, etc... Every display to be different than the previous one, you can use this function. It alternate the album by two fields.

You can use that function to push up the products that you want to display first. For exemple, I want that my first products are the one who are in stock, new and best seller in an alternative way, but too, with a different manufacturer.


//An example of array, you can get it from a query result.
$album[] = array('id'=>'4', 'style'=>'metal', 'type'=>'best seller','dummy_field'=>'dummy value');
$album[] = array('id'=>'5', 'style'=>'metal', 'type'=>'legend', 	'dummy_field'=>'dummy value');
$album[] = array('id'=>'6', 'style'=>'metal', 'type'=>'new', 		'dummy_field'=>'dummy value');
$album[] = array('id'=>'7', 'style'=>'metal', 'type'=>'best seller','dummy_field'=>'dummy value');
$album[] = array('id'=>'8', 'style'=>'metal', 'type'=>'legend', 	'dummy_field'=>'dummy value');
$album[] = array('id'=>'9', 'style'=>'metal', 'type'=>'new', 		'dummy_field'=>'dummy value');

$album[] = array('id'=>'10', 'style'=>'pop', 'type'=>'best seller', 'dummy_field'=>'dummy value');
$album[] = array('id'=>'11', 'style'=>'pop', 'type'=>'legend', 		'dummy_field'=>'dummy value');
$album[] = array('id'=>'12', 'style'=>'pop', 'type'=>'new', 		'dummy_field'=>'dummy value');
$album[] = array('id'=>'13', 'style'=>'pop', 'type'=>'best seller', 'dummy_field'=>'dummy value');
$album[] = array('id'=>'14', 'style'=>'pop', 'type'=>'legend', 		'dummy_field'=>'dummy value');
$album[] = array('id'=>'15', 'style'=>'pop', 'type'=>'new', 		'dummy_field'=>'dummy value');

$album[] = array('id'=>'16', 'style'=>'rock', 'type'=>'best seller','dummy_field'=>'dummy value');
$album[] = array('id'=>'17', 'style'=>'rock', 'type'=>'legend', 	'dummy_field'=>'dummy value');
$album[] = array('id'=>'18', 'style'=>'rock', 'type'=>'new', 		'dummy_field'=>'dummy value');
$album[] = array('id'=>'19', 'style'=>'rock', 'type'=>'best seller','dummy_field'=>'dummy value');
$album[] = array('id'=>'20', 'style'=>'rock', 'type'=>'legend', 	'dummy_field'=>'dummy value');
$album[] = array('id'=>'21', 'style'=>'rock', 'type'=>'new', 		'dummy_field'=>'dummy value');

/**
*
*	$arrays	is the result of your query. (array of array) or (array of object)
*	$field	is the three fields you want to use to sort your rows
*			by default it take the three first.
*	$return_array	it return all your field, or just the first one.
*	$as_object		If you want to return like an array of object 
*
*/
function alternativeSorting($arrays, $field=NULL, $return_array=true, $as_object=false)
{
	//We build data for the sorting
	foreach($arrays as $new_array) :
		$new_array = (array) $new_array;
		if(count($field) == 3) {
			$first=$new_array[$field[0]];
			$second=$new_array[$field[1]];
			$third=$new_array[$field[2]];
		}
		else {
		//If no fields are specify in the arguments, we take the three first fields
			reset($new_array); 
			$first=current($new_array);
			$second=next($new_array);
			$third=next($new_array);
		}
		
		//We build an array with the first field.
		$array[$first] = $first;
		//We build an array with the second field an we link it to the first field
		$array_sort1[$second][$first]=$first;
		//We build an array with the third field an we link it to the first field
		$array_sort2[$third][$first]=$first;
		
		//We build an array with a distinct value of the second field
		$swap1[$second]=$second;
		//We build an array with a distinct value of the third field
		$swap2[$third] = $third; 
		
		//It's the array that we will return
		if($return_array)
			$array_result[$first]=$new_array;
	endforeach;
		
	//We initialize the variable return in case of no result.
	$result=array();
	
	//We loop until our array is not empty
	while(count($array)>0) :
		unset($result_array);
		unset($current_swap);
		
		//We get the two values to alternate
		$key1=current($swap1); //ex: 'metal'  
		$key2=current($swap2); //ex: 'best seller'
		
		//We are looking for if the key1 and key2 have a result 
		//If not we get the next key1 value (ex: pop)
		//It return an array with all the matches or nothing if there's no matches
		while(empty($result_array)){
			$result_array = array_intersect_assoc($array_sort1[$key1], $array_sort2[$key2]);
			if(empty($result_array)):

				next($swap1);
				if(current($swap1)=="") reset($swap1);
				if(current($swap1)==$current_swap) { break;}
				
				if(empty($current_swap))
					$current_swap = $key1;
					
				$key1=current($swap1);	
			endif;
		}
		
		//We can have several matches, so we get only the first
		$current_id = current($result_array);
		
		//If there is no more matches for the case, we just unset the part of the array
		//in order to not test it anymore
		if($current_id == "") :
			unset($array_sort2[$key2]);
			$swapKey = array_search($key2,$swap2);
			unset($swap2[$swapKey]);
		else :
			//We build an array for the result
			if($return_array){
				if($as_object)
					$result[$current_id] = (object) $array_result[$current_id];
				else
					$result[$current_id] = $array_result[$current_id];
			}else
				$result[$current_id] = $current_id;
		endif;
		
		//We unset the value that we already took
		unset($array[$current_id]);
		unset($array_sort1[$key1][$current_id]);
		unset($array_sort2[$key2][$current_id]);
		
		//We take the next value to test
		next($swap1);
		if(current($swap1)=="") reset($swap1);
		next($swap2);
		if(current($swap2)=="") reset($swap2);

	endwhile;

	return $result;
}

$test = alternativeSorting($album, array('id','style','type'), true, true);

print_r($test);


Array
(
    [4] => stdClass Object
        (
            [id] => 4
            [style] => metal
            [type] => best seller
            [dummy_field] => dummy value
        )

    [11] => stdClass Object
        (
            [id] => 11
            [style] => pop
            [type] => legend
            [dummy_field] => dummy value
        )

    [18] => stdClass Object
        (
            [id] => 18
            [style] => rock
            [type] => new
            [dummy_field] => dummy value
        )

    [7] => stdClass Object
        (
            [id] => 7
            [style] => metal
            [type] => best seller
            [dummy_field] => dummy value
        )

    [14] => stdClass Object
        (
            [id] => 14
            [style] => pop
            [type] => legend
            [dummy_field] => dummy value
        )

    [21] => stdClass Object
        (
            [id] => 21
            [style] => rock
            [type] => new
            [dummy_field] => dummy value
        )

    [10] => stdClass Object
        (
            [id] => 10
            [style] => pop
            [type] => best seller
            [dummy_field] => dummy value
        )

    [17] => stdClass Object
        (
            [id] => 17
            [style] => rock
            [type] => legend
            [dummy_field] => dummy value
        )

    [6] => stdClass Object
        (
            [id] => 6
            [style] => metal
            [type] => new
            [dummy_field] => dummy value
        )

    [13] => stdClass Object
        (
            [id] => 13
            [style] => pop
            [type] => best seller
            [dummy_field] => dummy value
        )

    [20] => stdClass Object
        (
            [id] => 20
            [style] => rock
            [type] => legend
            [dummy_field] => dummy value
        )

    [9] => stdClass Object
        (
            [id] => 9
            [style] => metal
            [type] => new
            [dummy_field] => dummy value
        )

    [16] => stdClass Object
        (
            [id] => 16
            [style] => rock
            [type] => best seller
            [dummy_field] => dummy value
        )

    [5] => stdClass Object
        (
            [id] => 5
            [style] => metal
            [type] => legend
            [dummy_field] => dummy value
        )

    [12] => stdClass Object
        (
            [id] => 12
            [style] => pop
            [type] => new
            [dummy_field] => dummy value
        )

    [19] => stdClass Object
        (
            [id] => 19
            [style] => rock
            [type] => best seller
            [dummy_field] => dummy value
        )

    [8] => stdClass Object
        (
            [id] => 8
            [style] => metal
            [type] => legend
            [dummy_field] => dummy value
        )

    [15] => stdClass Object
        (
            [id] => 15
            [style] => pop
            [type] => new
            [dummy_field] => dummy value
        )

)

Add comment