在Codeigniter上解析和忽略多维数组中的空数据

时间:2019-02-12 11:00:19

标签: php arrays json codeigniter multidimensional-array

我有多维数组,该数组从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 :(得分:1)

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

希望这会有所帮助。

答案 1 :(得分:0)

尝试一下:

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

答案 2 :(得分:0)

尝试一下,我做了几行更改

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

}

答案 3 :(得分:0)

将json解码为数组数组。

使用LongStream删除空值。

使用array_filter()重新索引结果。

最后重新编码为json。

https://3v4l.org/fgKSd

array_values()

输出:

$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()并不能满足您的需求)。

一种最佳解决方案是重新设计您的sql查询,以消除查询中的空结果(最早)。我觉得用INNER JOIN替换LEFT JOIN将解决此问题。另外,您应在查询中使用表别名,以避免重写变量表名称,并通常提高代码的简洁性/可读性。最佳实践是在编写mysql关键字时使用ALL CAPS。

reset()

如果出于某种奇怪的原因,INNER JOIN不是解决方案,那么您可以使用HAVING子句过滤掉仅其中一列中具有NULL值的行。

仅供参考:无需像这样的函数调用就可以压入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(); }

$test