统一排列/分配数组项 [英] Arrange/distribute array items uniformly
问题描述
我有一个具有 type
属性的多维关联数组.看起来像这样:
I have a multidimensional associative array with a type
property. It looks like this:
$data = array(
array( "name" => "SomeName", "type" => "A"),
array( "name" => "SomeName", "type" => "A"),
array( "name" => "SomeName", "type" => "A"),
array( "name" => "SomeName", "type" => "A"),
array( "name" => "SomeName", "type" => "A"),
array( "name" => "SomeName", "type" => "B"),
array( "name" => "SomeName", "type" => "B"),
array( "name" => "SomeName", "type" => "B"),
array( "name" => "SomeName", "type" => "C"),
array( "name" => "SomeName", "type" => "C")
);
我想重新排列它以使项目更均匀地分布(如果可能的话,使用最少的重复类型).它应该看起来像这样:
I want to rearrange it to make the items more equally distributed (with least amount of repetitive types if possible). It should look like this:
array(
array( "name" => "SomeName", "type" => "A"),
array( "name" => "SomeName", "type" => "B"),
array( "name" => "SomeName", "type" => "A"),
array( "name" => "SomeName", "type" => "C"),
array( "name" => "SomeName", "type" => "A"),
array( "name" => "SomeName", "type" => "B"),
array( "name" => "SomeName", "type" => "A"),
array( "name" => "SomeName", "type" => "C"),
array( "name" => "SomeName", "type" => "A"),
array( "name" => "SomeName", "type" => "B")
);
到目前为止,我一直在尝试找到每种类型和总数的计数:
What I've tried so far was to find the count for each type and the total:
$count_a = 5;
$count_b = 3;
$count_c = 2;
$total = 10;
还有每种类型的比率:
$ratio_a = 0.5; //(5/10)
$ratio_b = 0.3; //(3/10)
$ratio_c = 0.2; //(2/10)
我只是被困在这里.我是否应该尝试使用数字创建新的属性 index
,然后根据该数字进行排序?或者也许以某种方式使用模运算符?我还尝试了将项目分成3个不同的数组,如果这样做更容易的话.
I'm just stuck here. Should I try to make a new property index
with a number and then sort based on it? Or maybe use modulo operator somehow? I've also tried separating the items into 3 different arrays if that makes it any easier.
推荐答案
您应该对已排序类型进行排序,并逐步进行逐步遍历,逐一更改所选类型.
You should take a sorted array of sorted types and do iterative walk through it step by step changing selected type by one.
$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);
代码按ABCABCABAA的顺序输出元素.
The code outputs elements in order of ABCABCABAA.
UPD.如果 count(maxtype)
> count(nexttype)+ 1
这篇关于统一排列/分配数组项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!