Разбор и игнорирование нулевых данных внутри многомерного массива на Codeigniter - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть многомерный массив, который показан из print_r (json_encode ($ test));в моем контроллере так:

[[],[],[],[],[],[],[],[],[],[],[{"Username":"arnab@tmail.com","Role":"Software Engineer","today":"139","weekly":"391","monthly":"1149","yearly":"1149"},{"Username":"dolly@fmail.com","Role":"DevOps","today":"251","weekly":"405","monthly":"736","yearly":"736"}]]

И мой код:

public function getUserAchievement(){
    $test = array();
    $res = array();
    $data = $this->queries_trend->getDataCustomer();
    foreach ($data as $key => $value) {
            array_push($test, $this->passing($value['Customer'], $value['Project']));
    }
    print_r(json_encode($test));
}

public function passing($customer, $project){
    $date = DATE("Y-m-d");
    $time = DATE("H:i:s");
    $query = $this->db->query("SELECT t_closed_by As Username, ixt_user_type.user_owner As Role,
                  COUNT( case when t_closed_time > curdate() - interval 1 day THEN 1 END ) as today,
                  COUNT( case when t_closed_time > curdate() - interval 7 day THEN 1 END ) as weekly,
                  COUNT( case when t_closed_time > curdate() - interval 1 month THEN 1 END ) as monthly,
                  COUNT( case when t_closed_time > curdate() - interval 1 year THEN 1 END ) as yearly
                FROM p_".$customer."_".$project."_ticket
                LEFT JOIN m_event_type ON p_".$customer."_".$project."_ticket.t_req_type = m_event_type.ev_type
                LEFT JOIN ixt_user_type ON m_event_type.ev_user_type_target = ixt_user_type.user_type
                WHERE t_status = 9
                GROUP BY t_closed_by; ")->result_array();
     return $query;
}

Мой вопрос: как отфильтровать данные, если в многомерном массиве есть условный нулевой массив, и преобразовать в подобное?это:

[[{"Username":"arnab@tmail.com","Role":"Software Engineer","today":"139","weekly":"391","monthly":"1149","yearly":"1149"}],[{"Username":"dolly@fmail.com","Role":"DevOps","today":"251","weekly":"405","monthly":"736","yearly":"736"}]]

Нужна помощь, спасибо, ребята ...

Ответы [ 4 ]

0 голосов
/ 12 февраля 2019

Декодируйте ваш json в массив массивов.

Используйте array_filter() для удаления нулей.

Используйте array_values() для переиндексации результата.

Наконец, повторно-кодировать в json.

https://3v4l.org/fgKSd

$array = json_decode('[[],[],[],[],[],[],[],[],[],[],[{"Username":"arnab@tmail.com","Role":"Software Engineer","today":"139","weekly":"391","monthly":"1149","yearly":"1149"},{"Username":"dolly@fmail.com","Role":"DevOps","today":"251","weekly":"405","monthly":"736","yearly":"736"}]]', true);
echo json_encode(array_values(array_filter($array)));

Вывод:

[[{"Username":"arnab@tmail.com","Role":"Software Engineer","today":"139","weekly":"391","monthly":"1149","yearly":"1149"},{"Username":"dolly@fmail.com","Role":"DevOps","today":"251","weekly":"405","monthly":"736","yearly":"736"}]]

Приведенное выше использование array_filter() затем array_values() удаляет пустые подмассивы, а затемназначает новые индексы для выходного массива (reset() не делает то, что вам нужно).

Оптимальным решением было бы изменить дизайн вашего sql-запроса, чтобы исключить пустые результаты из запроса (с самой ранней точки),У меня такое чувство, что замена ЛЕВЫХ СОЕДИНЕНИЙ на ВНУТРЕННИЕ СОЕДИНЕНИЯ решит проблему.Кроме того, вы должны использовать псевдонимы таблиц в своем запросе, чтобы избежать перезаписи имени таблицы переменных и, как правило, улучшить краткость / читаемость кода.В качестве наилучшей практики используйте ВСЕ КАПАНЫ при написании ключевых слов mysql.

public function passing($customer, $project) {
return $this->db->query(
    "SELECT t_closed_by AS Username,
            iutypes.user_owner AS Role,
            COUNT(CASE WHEN t_closed_time > CURDATE() - INTERVAL 1 DAY THEN 1 END) AS today,
            COUNT(CASE WHEN t_closed_time > CURDATE() - INTERVAL 7 DAY THEN 1 END) AS weekly,
            COUNT(CASE WHEN t_closed_time > CURDATE() - INTERVAL 1 MONTH THEN 1 END) AS monthly,
            COUNT(CASE WHEN t_closed_time > CURDATE() - INTERVAL 1 YEAR THEN 1 END) AS yearly
    FROM p_".$customer."_".$project."_ticket AS tickets
    INNER JOIN m_event_type AS metypes ON tickets.t_req_type = metypes.ev_type
    INNER JOIN ixt_user_type AS iutypes ON metypes.ev_user_type_target = iutypes.user_type
    WHERE t_status = 9
    GROUP BY t_closed_by"
    )->result_array();
}

Если по какой-то странной причине INNER JOIN не является исправлением, вы можете использовать предложение HAVING для фильтрации строк, имеющих значение NULL, только в одном из столбцов.

К вашему сведению: нажатие на $test может быть выполнено без вызова функции, например:

$test[] = $this->passing($value['Customer'], $value['Project']);
0 голосов
/ 12 февраля 2019

попробуйте, я внес несколько изменений

public function getUserAchievement(){
    $test = array();
    $res = array();
    $data = $this->queries_trend->getDataCustomer();
    foreach ($data as $key => $value) {
        $resultPassing = $this->passing($value['Customer'], $value['Project']);
        echo'<pre>';print_r($resultPassing);
        if(!empty($resultPassing)){
            array_push($test, $resultPassing);
        }
    }
    print_r(json_encode($test));die;
}
public function passing($customer, $project){
    $date = DATE("Y-m-d");
    $time = DATE("H:i:s");
    $query = $this->db->query("SELECT t_closed_by As Username, ixt_user_type.user_owner As Role,
                  COUNT( case when t_closed_time > curdate() - interval 1 day THEN 1 END ) as today,
                  COUNT( case when t_closed_time > curdate() - interval 7 day THEN 1 END ) as weekly,
                  COUNT( case when t_closed_time > curdate() - interval 1 month THEN 1 END ) as monthly,
                  COUNT( case when t_closed_time > curdate() - interval 1 year THEN 1 END ) as yearly
                FROM p_".$customer."_".$project."_ticket
                LEFT JOIN m_event_type ON p_".$customer."_".$project."_ticket.t_req_type = m_event_type.ev_type
                LEFT JOIN ixt_user_type ON m_event_type.ev_user_type_target = ixt_user_type.user_type
                WHERE t_status = 9
                GROUP BY t_closed_by; ");
    if ($query->num_rows() > 0) {
        return $query->result_array();
    }else{
        return "";
    }

}
0 голосов
/ 12 февраля 2019
  1. Используйте array_filter($array) для удаления всех элементов / внутренних массивов, которые являются нулевыми.
  2. Используйте rest($array) для возврата первого array(suitable in your case).
  3. Использованиеjson_encode($array) для возврата данных в формате json.

    $filtered_array = array_filter($test);
    print_r(json_encode(reset($filtered_array)));
    

Надеюсь, это поможет.

0 голосов
/ 12 февраля 2019

Попробуйте:

<?php
$array = '[[],[],[],[],[],[],[],[],[],[],[{"Username":"arnab@tmail.com","Role":"Software Engineer","today":"139","weekly":"391","monthly":"1149","yearly":"1149"},{"Username":"dolly@fmail.com","Role":"DevOps","today":"251","weekly":"405","monthly":"736","yearly":"736"}]]';

$array = json_decode($array);

$newArray = [];
foreach($array as $a){
    if ($a) {
        array_push($newArray, $a);
    }
}
var_dump($newArray);

В вашем случае обновите функцию getUserAchievement () до:

public function getUserAchievement(){
    $test = array();
    $res = array();
    $data = $this->queries_trend->getDataCustomer();
    foreach ($data as $key => $value) {
            array_push($test, $this->passing($value['Customer'], $value['Project']));
    }

    // print_r(json_encode($test));

    $newArray = [];
    foreach($test as $t){
        if ($t) {
            array_push($newArray, $t);
        }
    }
    var_dump($newArray);
}
...