重新构造使用数组\计数\值和数组\映射的PHP多维数组

重新构造使用数组\计数\值和数组\映射的PHP多维数组,php,arrays,laravel,Php,Arrays,Laravel,使用Laravel 5.6,我创建了一个多维数组,如下所示: array:8 [ 0 => array:2 [ 0 => "ELA-2" 1 => 7 ] 1 => array:2 [ 0 => "Science-3" 1 => 9 ] 2 => array:2 [ 0 => "ELA-1"

使用Laravel 5.6,我创建了一个多维数组,如下所示:

array:8 [   
    0 => array:2 [
        0 => "ELA-2"
        1 => 7   
    ]   
    1 => array:2 [
        0 => "Science-3"
        1 => 9   
    ]   
    2 => array:2 [
        0 => "ELA-1"
        1 => 5   
    ]   
    3 => array:2 [
        0 => "Science-2"
        1 => 9
    ]   
    4 => array:2 [
        0 => "ELA-4"
        1 => 2   
    ]   
    5 => array:2 [
        0 => "ELA-3"
        1 => 7   
    ]   
    6 => array:2 [
        0 => "Science-4"
        1 => 2   
    ]   
    7 => array:2 [
        0 => "Science-1"
        1 => 1   
    ] 
]
array:8 [   
    0 => array:3 [
        "Subject" => "ELA"
        "Level" => 2
        "Count" => 7   
    ]   
    1 => array:3 [
        "Subject" => "Science"
        "Level" => 3
        "Count" => 9 
    ]   
    2 => array:3 [
        "Subject" => "ELA"
        "Level" => 1
        "Count" => 5 
    ]   
    3 => array:3 [
        "Subject" => "Science"
        "Level" => 2
        "Count" => 9
    ]   
    4 => array:3 [
        "Subject" => "ELA"
        "Level" => 4
        "Count" => 2   
    ]   
    5 => array:3 [
        "Subject" => "ELA"
        "Level" => 3
        "Count" => 7  
    ]   
    6 => array:3 [
        "Subject" => "Science"
        "Level" => 4
        "Count" => 2   
    ]   
    7 => array:3 [
        "Subject" => "Science"
        "Level" => 1
        "Count" => 1  
    ] 
]
// create an empty array
$array_holder = [];

// loop through each student
foreach($class_students as $student) {

    // loop through each subject
    foreach($class_subjects as $subject) {

        // count each child at his/her level (rounded average)
        $childs_level = AssessmentData::where('student_id', $student->id)->where('subject_id', $subject->subject_id)->avg('assessed_level');

        // get the subject name
        $current_subject = Subject::where('id', $subject->subject_id)->first();

        // round the average
        $childs_level = round($childs_level);

        // convert the childs_level into a whole number
        $childs_level = number_format($childs_level, 0);

        // add each child by appending to an array
        if ($childs_level != 0) {
            $compiled_array[] = array_push($array_holder, $current_subject->short_name."-".$childs_level);
        }
    }
}

// count each assessed_level from the resultant array
$counted_array = array_count_values($array_holder);

// remap the array
$counted_array = array_map(null, array_keys($counted_array), $counted_array);
这是使用array\u count\u值和array\u map创建的

我希望数据如下所示:

array:8 [   
    0 => array:2 [
        0 => "ELA-2"
        1 => 7   
    ]   
    1 => array:2 [
        0 => "Science-3"
        1 => 9   
    ]   
    2 => array:2 [
        0 => "ELA-1"
        1 => 5   
    ]   
    3 => array:2 [
        0 => "Science-2"
        1 => 9
    ]   
    4 => array:2 [
        0 => "ELA-4"
        1 => 2   
    ]   
    5 => array:2 [
        0 => "ELA-3"
        1 => 7   
    ]   
    6 => array:2 [
        0 => "Science-4"
        1 => 2   
    ]   
    7 => array:2 [
        0 => "Science-1"
        1 => 1   
    ] 
]
array:8 [   
    0 => array:3 [
        "Subject" => "ELA"
        "Level" => 2
        "Count" => 7   
    ]   
    1 => array:3 [
        "Subject" => "Science"
        "Level" => 3
        "Count" => 9 
    ]   
    2 => array:3 [
        "Subject" => "ELA"
        "Level" => 1
        "Count" => 5 
    ]   
    3 => array:3 [
        "Subject" => "Science"
        "Level" => 2
        "Count" => 9
    ]   
    4 => array:3 [
        "Subject" => "ELA"
        "Level" => 4
        "Count" => 2   
    ]   
    5 => array:3 [
        "Subject" => "ELA"
        "Level" => 3
        "Count" => 7  
    ]   
    6 => array:3 [
        "Subject" => "Science"
        "Level" => 4
        "Count" => 2   
    ]   
    7 => array:3 [
        "Subject" => "Science"
        "Level" => 1
        "Count" => 1  
    ] 
]
// create an empty array
$array_holder = [];

// loop through each student
foreach($class_students as $student) {

    // loop through each subject
    foreach($class_subjects as $subject) {

        // count each child at his/her level (rounded average)
        $childs_level = AssessmentData::where('student_id', $student->id)->where('subject_id', $subject->subject_id)->avg('assessed_level');

        // get the subject name
        $current_subject = Subject::where('id', $subject->subject_id)->first();

        // round the average
        $childs_level = round($childs_level);

        // convert the childs_level into a whole number
        $childs_level = number_format($childs_level, 0);

        // add each child by appending to an array
        if ($childs_level != 0) {
            $compiled_array[] = array_push($array_holder, $current_subject->short_name."-".$childs_level);
        }
    }
}

// count each assessed_level from the resultant array
$counted_array = array_count_values($array_holder);

// remap the array
$counted_array = array_map(null, array_keys($counted_array), $counted_array);
我不知道如何:

将每个数组中键[0]的值分开,并将其分为两部分:第一部分为“主题”,第二部分为“级别” 重新标记数字递增键,每个数组中将有3个分别标记为单词Subject、Level和Count。 我当前的代码如下所示:

array:8 [   
    0 => array:2 [
        0 => "ELA-2"
        1 => 7   
    ]   
    1 => array:2 [
        0 => "Science-3"
        1 => 9   
    ]   
    2 => array:2 [
        0 => "ELA-1"
        1 => 5   
    ]   
    3 => array:2 [
        0 => "Science-2"
        1 => 9
    ]   
    4 => array:2 [
        0 => "ELA-4"
        1 => 2   
    ]   
    5 => array:2 [
        0 => "ELA-3"
        1 => 7   
    ]   
    6 => array:2 [
        0 => "Science-4"
        1 => 2   
    ]   
    7 => array:2 [
        0 => "Science-1"
        1 => 1   
    ] 
]
array:8 [   
    0 => array:3 [
        "Subject" => "ELA"
        "Level" => 2
        "Count" => 7   
    ]   
    1 => array:3 [
        "Subject" => "Science"
        "Level" => 3
        "Count" => 9 
    ]   
    2 => array:3 [
        "Subject" => "ELA"
        "Level" => 1
        "Count" => 5 
    ]   
    3 => array:3 [
        "Subject" => "Science"
        "Level" => 2
        "Count" => 9
    ]   
    4 => array:3 [
        "Subject" => "ELA"
        "Level" => 4
        "Count" => 2   
    ]   
    5 => array:3 [
        "Subject" => "ELA"
        "Level" => 3
        "Count" => 7  
    ]   
    6 => array:3 [
        "Subject" => "Science"
        "Level" => 4
        "Count" => 2   
    ]   
    7 => array:3 [
        "Subject" => "Science"
        "Level" => 1
        "Count" => 1  
    ] 
]
// create an empty array
$array_holder = [];

// loop through each student
foreach($class_students as $student) {

    // loop through each subject
    foreach($class_subjects as $subject) {

        // count each child at his/her level (rounded average)
        $childs_level = AssessmentData::where('student_id', $student->id)->where('subject_id', $subject->subject_id)->avg('assessed_level');

        // get the subject name
        $current_subject = Subject::where('id', $subject->subject_id)->first();

        // round the average
        $childs_level = round($childs_level);

        // convert the childs_level into a whole number
        $childs_level = number_format($childs_level, 0);

        // add each child by appending to an array
        if ($childs_level != 0) {
            $compiled_array[] = array_push($array_holder, $current_subject->short_name."-".$childs_level);
        }
    }
}

// count each assessed_level from the resultant array
$counted_array = array_count_values($array_holder);

// remap the array
$counted_array = array_map(null, array_keys($counted_array), $counted_array);
附加请求-排序


我希望结果按计数排序,以便级别1为第一,级别2为第二,级别3为第三,级别4为第四。目前,它是按相反的顺序排序的-级别4是第一级,级别3是第二级,等等。

您必须循环原始数组并创建一个新数组:

<?php
$original_array = [
    ['ELA-2', 7],
    ['Science-3', 9],
    ['ELA-1', 5]
    // you can fill in the rest
];

$new_array = [];
foreach($original_array as $v)
{
    $new_array[] = [
        'Subject' => explode('-', $v[0])[0], // split the subject on "-" and retrieve the first item
        'Level' => explode('-', $v[0])[1], // split the subject on "-" and retrieve the second item
        'Count' => $v[1] // this is given to us so just use it
    ];
}

// Sort the finished product in ascending order based on the "count" of the sub-arrays
//
// You can also use this earlier on $original_array if you want
// but you would just change the arithmetic to $a[ 1 ] - $b [ 1 ]
usort( $new_array, function( $a, $b ){
    return $a[ 'Count' ] - $b[ 'Count' ];
} );

print_r($new_array);
如果您想获得新奇感,那么这将实现与foreach{}相同的结果:


我想添加一种替代方法。 重要提示:

不要要求PHP对同一字符串执行两次相同的分解调用——将其作为临时变量缓存,或者如我的代码片段所示,同时使用所有生成的元素。 通过声明limit参数3rd param来限制explode调用,以便输出一致,并且脚本清楚地了解预期的操作,因为不需要输入数据来理解意图。 usort中的spaceship操作符用途非常广泛,允许您在不更改语法的情况下进行各种比较。 代码:

我注意到,在您的问题中,您要求按计数对数据进行排序,但随后继续解释您希望如何按级别进行排序-这是不明确的

如果要按计数排序,只需使用:

usort($assoc_array, function($a, $b) {
    return $a['Count'] <=> $b['Count'];
});

无需在我的代码中争论这个解决方案,就可以开始了。非常感谢你的明确回答@谢尔顿·斯科特,不客气!需要注意的一点是,如果主题有多个连字符,如Bio-Science-3-2或其他什么,那么使用explode'-',$v[0][0]将不理想,需要添加更多的处理逻辑。我如何才能按降序对数组进行排序?当前是升序。@SheldonScott您能定义降序吗?什么样的标准将一个主题置于另一个主题之前?如果您愿意,请在您的初始问题中提供所需排序顺序的示例。@SheldonScott哈哈,谢谢!学习遍历和操作数组很可能对实现优雅的解决方案产生了最大的积极影响,因此我很高兴能与其他人分享