Reputation: 194
I have a multi-dimensional array as follows:
$lee[] = array("question" => "3", "appeared" => "0");
$lee[] = array("question" => "4", "appeared" => "1");
$lee[] = array("question" => "5", "appeared" => "0");
$lee[] = array("question" => "6", "appeared" => "0");
$lee[] = array("question" => "7", "appeared" => "1");
$lee[] = array("question" => "8", "appeared" => "1");
$lee[] = array("question" => "9", "appeared" => "2");
$lee[] = array("question" => "10", "appeared" => "0");
$lee[] = array("question" => "12", "appeared" => "3");
$lee[] = array("question" => "15", "appeared" => "3");
$lee[] = array("question" => "19", "appeared" => "3");
function array_sort_by_column(&$arr, $col, $dir = SORT_ASC) {
$sort_col = array();
foreach ($arr as $key=> $row) {
$sort_col[$key] = $row[$col];
}
array_multisort($sort_col, $dir, $arr);
}
array_sort_by_column($lee, 'appeared');
So far so good - now my array is sorted by the 'appeared' column in ascending order.
Now comes the problem. I want to randomly shuffle the array, but still maintaining the "appeared" column in ascending order
How can this be done? I have no clue..
Upvotes: 1
Views: 1132
Reputation: 47883
It seems to me that these other answers are over-engineered (no wonder you can't follow what they do). You only need two function calls, shuffle()
then usort()
. There is no need to group them at all. (I'm going use the "spaceship" operator in my demo, but you can use any of the old-school comparison techniques if your php version requires it.)
Code: (Demo)
shuffle($lee); // shuffle the array
usort($lee,function($a,$b){return $a['appeared']<=>$b['appeared'];}); // sort shuffled array by appeared value
var_export($lee);
Possible Output:
array (
0 =>
array (
'question' => '10',
'appeared' => '0',
),
1 =>
array (
'question' => '5',
'appeared' => '0',
),
2 =>
array (
'question' => '6',
'appeared' => '0',
),
3 =>
array (
'question' => '3',
'appeared' => '0',
),
4 =>
array (
'question' => '4',
'appeared' => '1',
),
5 =>
array (
'question' => '8',
'appeared' => '1',
),
6 =>
array (
'question' => '7',
'appeared' => '1',
),
7 =>
array (
'question' => '9',
'appeared' => '2',
),
8 =>
array (
'question' => '12',
'appeared' => '3',
),
9 =>
array (
'question' => '15',
'appeared' => '3',
),
10 =>
array (
'question' => '19',
'appeared' => '3',
),
)
p.s. Ordering by appeared
DESC is as simple as swapping $a
and $b
after return
.
Upvotes: 1
Reputation: 2327
<?php
$lee[] = array("question" => "3", "appeared" => "0");
$lee[] = array("question" => "4", "appeared" => "1");
$lee[] = array("question" => "5", "appeared" => "0");
$lee[] = array("question" => "6", "appeared" => "0");
$lee[] = array("question" => "7", "appeared" => "1");
$lee[] = array("question" => "8", "appeared" => "1");
$lee[] = array("question" => "9", "appeared" => "2");
$lee[] = array("question" => "10", "appeared" => "0");
$lee[] = array("question" => "12", "appeared" => "3");
$lee[] = array("question" => "15", "appeared" => "3");
$lee[] = array("question" => "19", "appeared" => "3");
function array_sort_by_column(&$arr, $col, $dir = SORT_ASC) {
$sort_col = array();
foreach ($arr as $key=> $row) {
$sort_col[$key] = $row[$col];
}
array_multisort($sort_col, $dir, $arr);
}
array_sort_by_column($lee, 'appeared');
foreach( $lee as $row){
$question[] = $row['question'];
}
shuffle($question);
for($i=0;$i<count($lee);$i++){
$lee[$i]['question'] = $question[$i];
}
echo "<pre>";print_r($lee);
Upvotes: 0
Reputation: 54831
$lee[] = array("question" => "3", "appeared" => "0");
$lee[] = array("question" => "4", "appeared" => "1");
$lee[] = array("question" => "5", "appeared" => "0");
$lee[] = array("question" => "6", "appeared" => "0");
$lee[] = array("question" => "7", "appeared" => "1");
$lee[] = array("question" => "8", "appeared" => "1");
$lee[] = array("question" => "9", "appeared" => "2");
$lee[] = array("question" => "10", "appeared" => "0");
$lee[] = array("question" => "12", "appeared" => "3");
$lee[] = array("question" => "15", "appeared" => "3");
$lee[] = array("question" => "19", "appeared" => "3");
$parts = [];
// Group items by `appeared` value
foreach ($lee as $item) {
$parts[$item['appeared']][] = $item;
}
// shuffle each group
foreach ($parts as &$part) {
shuffle($part);
}
// sort array by keys in ascending order
ksort($parts);
// merge groups to one array
print_r(call_user_func_array('array_merge', $parts));
Upvotes: 1