<?php
$data = array(
array( "name" => "SomeName1", "type" => "A"),
array( "name" => "SomeName2", "type" => "A"),
array( "name" => "SomeName3", "type" => "A"),
array( "name" => "SomeName4", "type" => "A"),
array( "name" => "SomeName5", "type" => "A"),
array( "name" => "SomeName6", "type" => "B"),
array( "name" => "SomeName7", "type" => "B"),
array( "name" => "SomeName8", "type" => "B"),
array( "name" => "SomeName9", "type" => "C"),
array( "name" => "SomeName0", "type" => "C")
);
$dataSorted = array();
$counts = array();
foreach($data as $elem) {
// just init values for a new type
if(!isset($counts[$elem['type']])) {
$counts[$elem['type']] = 0;
$dataByType[$elem['type']] = array();
}
// count types
$counts[$elem['type']]++;
// save it to grouped array
$dataByType[$elem['type']][] = $elem;
}
// sort it to A=>5, B=>3 C=>2
arsort($counts, SORT_NUMERIC);
// get sorted types as an array
$types = array_keys($counts);
// index will be looped 0 -> count($types) - 1 and then down to 0 again
$currentTypeIndex = 0;
// make a walk on sorted array. First get the most popular, then less popular etc.
// when all types are added, repeat
while(count($dataSorted) < count($data)) {
$currentType = $types[$currentTypeIndex];
// skip adding if we ran out this type
if($counts[$currentType]) {
// pop an element of selected type
$dataSorted[] = array_pop($dataByType[$currentType]);
// decrease counter
$counts[$currentType]--;
}
// choose next type
$currentTypeIndex = (++$currentTypeIndex)%count($types);
}
print_r($dataSorted);