Как я могу получить наибольшее значение из массива? Например, я пытаюсь получить максимальный результат каждого теста вместо нескольких результатов одного теста.
У меня есть массив, который выглядит так:
[
{
"ID":"806",
"user_login":"123456789",
"post_title":"Foo Test 1",
"display_name":"John Doe",
"activity_meta_value":"100",
"activity_completed":"1543142130"},
{
"ID":"806",
"user_login":"123456789",
"post_title":"Foo Test 2",
"display_name":"John Doe",
"activity_meta_value":"75",
"activity_completed":"1543144312"},
{
"ID":"806",
"user_login":"123456789",
"post_title":"Foo Test 2",
"display_name":"John Doe",
"activity_meta_value":"75",
"activity_completed":"1543144528"},
{
"ID":"1167",
"user_login":"987654321",
"post_title":"Foo Test 2",
"display_name":"Karen Eliot",
"activity_meta_value":"75",
"activity_completed":"1543156089"},
{
"ID":"1167",
"user_login":"987654321",
"post_title":"Foo Test 2",
"display_name":"Karen Eliot",
"activity_meta_value":"100",
"activity_completed":"1543156480"}
]
Затем я переставляю массив в следующую структуру, чтобы с ним было легче работать. это вывод массива после того, как я его переставил.
[
{
"id":"806",
"user_login":"123456789",
"user_name":"John Doe",
"quizes":[
{
"quiz":"Foo Test 1",
"score":"90",
"quiz_completed":"1543141990"},
{
"quiz":"Foo Test 1",
"score":"100",
"quiz_completed":"1543142130"},
{
"quiz":"Foo Test 2",
"score":"75",
"quiz_completed":"1543144312"},
{
"quiz":"Foo Test 2",
"score":"75",
"quiz_completed":"1543144528"}
]
},
{
"id":"1167",
"user_login":"987654321",
"user_name":"Karen Eliot",
"quizes":[
{
"quiz":"Foo Test 2",
"score":"75",
"quiz_completed":"1543156089"},
{
"quiz":"Foo Test 2",
"score":"100",
"quiz_completed":"1543156480"}
]
}
]
Я делаю это с помощью следующей функции:
function student_scores( $data ) {
global $wpdb;
$quizzes = $wpdb->get_results( " SELECT $wpdb->users.ID, $wpdb->users.user_login, $wpdb->posts.post_title, $wpdb->users.display_name, " . $wpdb->prefix . "learndash_user_activity_meta.activity_meta_value, " . $wpdb->prefix . "learndash_user_activity.activity_completed
FROM " . $wpdb->prefix . "learndash_user_activity
INNER JOIN $wpdb->users ON " . $wpdb->prefix . "learndash_user_activity.user_id = $wpdb->users.ID
INNER JOIN " . $wpdb->prefix . "learndash_user_activity_meta ON " . $wpdb->prefix . "learndash_user_activity.activity_id = " . $wpdb->prefix . "learndash_user_activity_meta.activity_id
INNER JOIN $wpdb->posts ON " . $wpdb->prefix . "learndash_user_activity.post_id = $wpdb->posts.ID
INNER JOIN $wpdb->usermeta ON $wpdb->users.ID = $wpdb->usermeta.user_id
WHERE " . $wpdb->prefix . "learndash_user_activity.activity_type = 'quiz' AND " . $wpdb->prefix . "learndash_user_activity_meta.activity_meta_key = 'percentage' AND " . $wpdb->prefix . "usermeta.meta_value = " . $data['id'] . "GROUP BY " . $wpdb->prefix . "learndash_user_activity.activity_id ", ARRAY_A );
$out = array();
foreach ( $quizzes as $x ) {
$out[ $x['ID'] ]['id'] = $x['ID'];
$out[ $x['ID'] ]['user_login'] = $x['user_login'];
$out[ $x['ID'] ]['user_name'] = $x['display_name'];
$out[ $x['ID'] ]['quizes'][] = array(
'quiz' => $x['post_title'],
'score' => $x['activity_meta_value'],
'quiz_completed' => $x['activity_completed']
);
}
if ( empty( $out ) ) {
return new WP_Error(
'no_students',
'invalid group',
array(
'status' => 404
)
);
}
return array_values( $out );
}
Я хочу получить максимальное значение для каждого теста для каждого пользователя. У каждого пользователя есть 2 теста, и я хочу получить более высокий балл за тот же тест. Например, если пользователь прошел тест Foo Test 1 дважды и получил 50 в первый раз и 70 во второй раз, я хотел бы вернуть только 70 для Foo Test 1.
Я надеюсь, что мой вопрос достаточно ясен. Заранее спасибо.
Вы уже выполнили большую часть работы, организовав тестовые элементы для каждого пользователя. Осталось отфильтровать этот список.
Предположим, у вас есть этот список «тест-элементов»: (как John Doe
в твоем примере)
$a = array("quiz" => "Foo Test 1", "score" => "90");
$b = array("quiz" => "Foo Test 1", "score" => "100");
$c = array("quiz" => "Foo Test 2", "score" => "75");
$d = array("quiz" => "Foo Test 2", "score" => "75");
$quizes = array($a, $b, $c, $d);
Вы можете сузить это:
$res = array();
foreach($quizes as $quize) {
if (!isset($res[$quize["quiz"]]) || ($res[$quize["quiz"]]["score"] < $quize["score"])) // is first test or this test higher then the previous
$res[$quize["quiz"]] = $quize;
}
$res = array_values($res); // because all you want are the quiz elements
Сейчас $res
будет выводить:
Array
(
[0] => Array
(
[quiz] => Foo Test 1
[score] => 100
)
[1] => Array
(
[quiz] => Foo Test 2
[score] => 75
)
)
Надеюсь, это поможет!
отредактированный
Определите следующую функцию:
function filterQuizesByScore($quizes) {
$res = array();
foreach($quizes as $quize) {
if (!isset($res[$quize["quiz"]]) || ($res[$quize["quiz"]]["score"] < $quize["score"]))
$res[$quize["quiz"]] = $quize;
}
return array_values($res);
}
Используйте это в student_scores
функция. После foreach ( $quizzes as $x )
объем добавить новый цикл как:
foreach($out as &$elem) {
$elem["quizes"] = filterQuizesByScore($elem["quizes"]);
}
Других решений пока нет …