Реструктуризация многомерного массива PHP, который использует array_count_values ​​и array_map - PullRequest
0 голосов
/ 03 мая 2018

Используя 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_count_values ​​и array_map (если это имеет значение).

Я хочу, чтобы данные выглядели так:

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  
    ] 
]

Я не уверен, как:

  1. разбивает значения из ключа [0] в каждом массиве и разделяет их на 2 части - первую часть для «Предмета» и вторую часть для «Уровня»
  2. переназначает цифровые увеличивающиеся ключи (будет 3 в каждом массиве) на слова «Subject», «Level» и «Count» соответственно.

Мой текущий код выглядит так:

// 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 - второй и т. Д.)

1 Ответ

0 голосов
/ 03 мая 2018

Вы должны зациклить исходный массив и создать новый:

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

Выход:

Array
(
    [0] => Array
        (
            [Subject] => ELA
            [Level] => 1
            [Count] => 5
        )

    [1] => Array
        (
            [Subject] => ELA
            [Level] => 2
            [Count] => 7
        )

    [2] => Array
        (
            [Subject] => Science
            [Level] => 3
            [Count] => 9
        )

)

Если вы хотите получить фантазию и array_map(), то это дает тот же результат, что и foreach(){}:

$new_array = array_map(
    function($v){
        return [
            '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
        ];
    },
    $original_array
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...