I have the following array
$records = array(
array("postId"=>"1","grid"=>"6"),
array("postId"=>"2","grid"=>"3"),
array("postId"=>"3","grid"=>"6"),
array("postId"=>"4","grid"=>"3"),
array("postId"=>"5","grid"=>"3"),
array("postId"=>"6","grid"=>"12"),
array("postId"=>"7","grid"=>"3"),
);
I want to sort this array in a way that the sum of any number of back to back "grids" is equals to 12.
Example: The values of the "grids" in the above array are : 6,3,6,3,3,12,3
(6+6=12), (3+3+3+3=12),(12=12) so the new order should be 6,6,3,3,3,3,12
or 3,3,3,3,12,6,6
or 6,3,3,6,3,3,12
So after sorting the array the new array should look like following:
$records=array(
array("postId"=>"1","grid"=>"6"),
array("postId"=>"3","grid"=>"6"),
array("postId"=>"2","grid"=>"3"),
array("postId"=>"4","grid"=>"3"),
array("postId"=>"5","grid"=>"3"),
array("postId"=>"7","grid"=>"3"),
array("postId"=>"6","grid"=>"12"),
);
I searched in php manual and found these functions: sort,uasort, uksort, usort but I couldn't figure out how to use them.
Could you please tell me how to achieve this using PHP ?
The value of grid will always be 3 or 6 or 12 (these three numbers only )
$records = array(
array("postId"=>"1","grid"=>"3"),
array("postId"=>"2","grid"=>"6"),
array("postId"=>"3","grid"=>"3"),
array("postId"=>"4","grid"=>"3"),
array("postId"=>"5","grid"=>"6"),
array("postId"=>"6","grid"=>"6"),
array("postId"=>"7","grid"=>"3"),
array("postId"=>"8","grid"=>"6"),
);
So you are not really sorting, but reordering to create sequence. I imagine that you are trying to do some layout of bricks with fixed height, and you need to have it reordered to fill each row and leave the rest at the end. With given fixed variants of 12,6,3
it can be done by sorting it in descending order - with odd number of sixes it will be filled with smaller threes. However such order will produce boring layout - to have it more interesting you only need to reorder some posts. For this you will need to create temporary container and merge it when sum of its grids is equal 12. If you are left with some temporary containers, merge them into one and sort descending before merging with previously grouped.
Code illustrating my concept:
//auxiliary function to calculate sum of grids in given temporary container
function reduc($a) {
return array_reduce($a, function ($result, $item) {
return $result . $item['grid'] . ',';
}, '');
}
function regroup($records, $group_sum = 12) {
$temp = array();
$grouped = array();
foreach ($records as $r) {
if ($r['grid'] == $group_sum) {
$grouped[] = $r;
} else {
if (!$temp) {
$temp[] = array($r);
} else {
$was_grouped = false;
foreach ($temp as $idx => $container) {
$current_sum = sum_collection($container);
if ($current_sum + $r['grid'] <= $group_sum) {
$temp[$idx][] = $r;
if ($current_sum + $r['grid'] == $group_sum) {
$grouped = array_merge($grouped, $temp[$idx]);
unset($temp[$idx]);
}
$was_grouped = true;
break;
}
}
if (!$was_grouped) {
$temp[] = array($r);
}
}
}
}
if ($temp) {
//Sort descending, so biggest ones will be filled first with smalller
$rest = call_user_func_array('array_merge', $temp);
usort($rest, function($a, $b) {
return $b['grid'] - $a['grid'];
});
$grouped = array_merge($grouped, $rest);
}
return $grouped;
}
The question is:
I want to sort this array in a way that the sum of any number of back to back "grids" is equals to 12.
You may try this (using usort)
$records = array(
array("postId"=>"1","grid"=>"6"),
array("postId"=>"2","grid"=>"3"),
array("postId"=>"3","grid"=>"6"),
array("postId"=>"4","grid"=>"3"),
array("postId"=>"5","grid"=>"3"),
array("postId"=>"6","grid"=>"12"),
array("postId"=>"7","grid"=>"3"),
);
You have number 3
4 times, nimber 6
2 times and number 12
once.
// Sort (ASC)
usort($records, function($a, $b) {
return $a['grid'] - $b['grid'];
});
DEMO-1 (ASC) (3+3+3+3=12
, 6+6=12
, 12=12
).
// Sort (DESC)
usort($records, function($a, $b) {
return $b['grid'] - $a['grid'];
});
DEMO-2 (DESC) (12=12
, 6+6=12
, 3+3+3+3=12
).
Output after sort using (ASC) :
Array (
[0] => Array ( [postId] => 7 [grid] => 3 ) [1] => Array ( [postId] => 5 [grid] => 3 ) [2] => Array ( [postId] => 4 [grid] => 3 ) [3] => Array ( [postId] => 2 [grid] => 3 ) [4] => Array ( [postId] => 3 [grid] => 6 ) [5] => Array ( [postId] => 1 [grid] => 6 ) [6] => Array ( [postId] => 6 [grid] => 12 )
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With