简体   繁体   English

在多维数组中找到最高值并保持最高值

[英]Find highest value in multidimensional array and keep highest

How can I get the highest value from an array?如何从数组中获取最高值? For example, I'm trying to get the highest result of each quiz instead of multiple results of the same test.例如,我试图获得每个测验的最高结果,而不是同一测试的多个结果。

I have an array that looks like this:我有一个看起来像这样的数组:

[
   {
      "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"
   }
]

I then rearrange the array to the following structure to make it easier to work with.然后我将数组重新排列为以下结构以使其更易于使用。 this is the output of the array after I rearranged it.这是我重新排列后数组的输出。

[
   {
      "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"
         }
      ]
   }
]

I do this by using the following function:我通过使用以下函数来做到这一点:

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 );
}

I want to get the highest value for each test per user.我想为每个用户的每个测试获得最高值。 Each user has 2 takes on a quiz, and I want to get the higher score of the same test.每个用户有 2 个测验,我想在同一个测试中获得更高的分数。 For example, if a user has taken quiz Foo Test 1 twice and gets 50 the first time and 70 the second time, I would like to return only the 70 for Foo Test 1.例如,如果用户参加了两次 Foo Test 1 测验,第一次得到 50,第二次得到 70,我只想返回 Foo Test 1 的 70。

I hope my question is clear enough.我希望我的问题足够清楚。 Thanks in advance.提前致谢。

You already done most of the job by arranging the test elements per user.通过为每个用户安排测试元素,您已经完成了大部分工作。 What remains is to filter this list.剩下的就是过滤这个列表。

Consider you have this list of "test-elements": (as John Doe in your example)考虑您有这个“测试元素”列表:(如您的示例中的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);

You can narrow it by:您可以通过以下方式缩小范围:

$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

Now $res will output:现在$res将输出:

Array
(
    [0] => Array
        (
            [quiz] => Foo Test 1
            [score] => 100
        )
    [1] => Array
        (
            [quiz] => Foo Test 2
            [score] => 75
        )
)

Hope that helps!希望有帮助!

Edited已编辑

Define the following function:定义以下函数:

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);
}

Use it in student_scores function.student_scores函数中使用它。 After foreach ( $quizzes as $x ) scope add new loop as:foreach ( $quizzes as $x )范围之后添加新循环为:

foreach($out as &$elem) {
    $elem["quizes"] = filterQuizesByScore($elem["quizes"]);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM