"1","grid"=>"6"), array("postId"=>"2","grid"=>"3"), ar...">

Array sort based on condition

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 so that the sum of any number of inverse β€œgrids” is 12.

Example: grid values ​​in the above array: 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 this:

 $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 could not figure out how to use them.

Could you tell me how to do this using PHP?

Update

The grid value will always be 3 or 6 or 12 (only these three numbers)

Problem

  $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"), ); 
+4
source share
4 answers

So, you really do not sort, but reorder to create a sequence. I assume that you are trying to make a model of bricks with a fixed height, and you will need to reorder it to fill each row and leave the rest at the end. Given fixed options 12,6,3 this can be done by sorting it in descending order - with an odd number of gears it will be filled with smaller triples. However, this order will create a boring layout - to make it more interesting, you only need to change the order of the messages. To do this, you need to create a temporary container and merge it when the sum of its grids is 12. If you stay with some temporary containers, merge them into one and sort them in descending order before merging with the previously grouped ones.

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; } 
+4
source

The question arises:

I want to sort this array so that the sum of any number back for the inverse "grids" is 12.

You can 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 sorting 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 ) 

)

+2
source

This solution is first sorted in descending order of the grid size, and then roughly makes it move down, checking each remaining element so far for each row:

 $sum=0; $grouped=array(); usort($records, function($a, $b) { return $a['grid']<$b['grid']; }); while ($records) { $next=reset($records); if ($sum) foreach ($records as $next) if ($sum+$next['grid']<=12) break; $grouped[]=$next; $sum+=$next['grid']; unset($records[array_search($next, $records)]); if ($sum>=12) $sum=0; } 

Update

It turns out that sorting in descending order is enough to solve the requirement using only 3, 6, and 12 elements. A 12, as well as 6, followed by 6, and all other combinations are filled with the remaining three. (For some reason, I thought the algorithm should be able to deal with nines.) So that’s all you need:

 usort($records, function($a, $b) { return $a['grid']<$b['grid']; }); 

This means that it is a very boring grid.

+1
source

In PHP> = 5.3.0 you can do this with usort() and closure (or globals as a hack). Given $records :

 $running_length = 0; usort( $records, function( $a, $b ) use( $running_length ) { $running_length += $a["grid"]; if( $running_length >= 12 ) return( true ); return( false ); }); 

If you visualize the grid parameter as the length of the string, the end result of $records becomes ordered, like:

 ... 3 ... 3 ...... 6 ... 3 ...... 6 ... 3 ............ 12 

Given the randomness of the pieces available, you can sort this array first from smallest to largest, and then see if it will be better organized for you. This method, obviously, does not detect fragmentation and blocks that do not match --- or cannot resolve their match.

0
source

All Articles