在php中为数组添加缺少日期索引

时间:2022-05-02 08:31:06

I have the following array from a count query:

我有一个计数查询中的以下数组:

array = (
  0=>array(
    'date'=>2017-09-01,
    'total'=>4
  ),
  1=>array(
    'date'=>2017-09-03,
    'total'=>6
  ),
  # and so on..
);

I want to fill the date even if my query has no records on that date! How can I add the missing date index to the array. The dates are to be sequential. so I want the following output:

即使我的查询在该日期没有记录,我想填写日期!如何将缺少的日期索引添加到数组中。日期是顺序的。所以我想要以下输出:

array = (
  0=>array(
    'date'=>2017-09-01,
    'total'=>4
  ),
  1=>array(
    'date'=>2017-09-02,
    'total'=>0
  )
  2=>array(
    'date'=>2017-09-03,
    'total'=>6
  ),

3 个解决方案

#1


2  

Extended solution with DateTime object, array_map and range functions:

使用DateTime对象,array_map和范围函数的扩展解决方案:

$arr = [
        ['date' => '2017-09-01', 'total' => 4],
        ['date' => '2017-09-07', 'total' => 6],
        ['date' => '2017-09-09', 'total' => 7]
];

$result = [];
foreach ($arr as $k => $item) {
    $d = new DateTime($item['date']);
    $result[] = $item;
    if (isset($arr[$k+1])) {
        $diff = (new DateTime($arr[$k+1]['date']))->diff($d)->days;
        if ($diff > 1) {
            $result = array_merge($result , array_map(function($v) use($d){
                $d_copy = clone $d;
                return [
                    'date' => $d_copy->add(new DateInterval('P' . $v. 'D'))->format('Y-m-d'),
                    'total' => 0
                ];
            }, range(1, $diff-1)));
        }
    }
}

print_r($result);

The output:

Array
(
    [0] => Array
        (
            [date] => 2017-09-01
            [total] => 4
        )

    [1] => Array
        (
            [date] => 2017-09-02
            [total] => 0
        )

    [2] => Array
        (
            [date] => 2017-09-03
            [total] => 0
        )

    [3] => Array
        (
            [date] => 2017-09-04
            [total] => 0
        )

    [4] => Array
        (
            [date] => 2017-09-05
            [total] => 0
        )

    [5] => Array
        (
            [date] => 2017-09-06
            [total] => 0
        )

    [6] => Array
        (
            [date] => 2017-09-07
            [total] => 6
        )

    [7] => Array
        (
            [date] => 2017-09-08
            [total] => 0
        )

    [8] => Array
        (
            [date] => 2017-09-09
            [total] => 7
        )
)

#2


1  

Here I create new arrays as reference.
One for all dates from first item in your array to last (range).
And one array with only the dates from your array so that I can search it.
This should handle more than one missing date and multiple missing dates.

在这里,我创建新的数组作为参考。一个适用于所有日期,从数组中的第一个项目到最后一个(范围)。一个数组只包含数组中的日期,以便我可以搜索它。这应该处理多个丢失日期和多个丢失日期。

$arr = array (
  0=>array(
    'date'=>'2017-09-01',
    'total'=>4
  ),
  1=>array(
    'date'=>'2017-09-07',
    'total'=>6
  )
);
// array with only dates to search in
$dates = array_column($arr, "date"); 

// Create an array with all dates from first item to last item
$start = new DateTime($arr[0]["date"]);
$end = new DateTime(end($arr)["date"]);

$range = new DatePeriod($start, new DateInterval('P1D'), $end);
// $range is now all dates from start to end minus last one.  

// Loop through the range 
foreach($range as $date){
    //See if the current date exist is first array
    $find = array_search($date->format("Y-m-d"), $dates);
    If($find !== false){
         $result[] = $arr[$find]; // if it does copy it to result array
    }Else{
         // If not add it and create a total = 0
         $result[] = array('date' => $date->format("Y-m-d"), 'total' => 0);
    }
}
// Since the loop does not loop all dates we need to add the last item to result.
$result[] = end($arr);
Var_dump($result);

https://3v4l.org/Hf73Z
Edit; forgot date ->format()

https://3v4l.org/Hf73Z编辑;忘了日期 - >格式()

#3


0  

Using an if statement try this :

使用if语句试试这个:

foreach($array as $ar){
if(!$ar["date"]){
 $ar["date"] = date("j- n- Y"); ;
 }
}

#1


2  

Extended solution with DateTime object, array_map and range functions:

使用DateTime对象,array_map和范围函数的扩展解决方案:

$arr = [
        ['date' => '2017-09-01', 'total' => 4],
        ['date' => '2017-09-07', 'total' => 6],
        ['date' => '2017-09-09', 'total' => 7]
];

$result = [];
foreach ($arr as $k => $item) {
    $d = new DateTime($item['date']);
    $result[] = $item;
    if (isset($arr[$k+1])) {
        $diff = (new DateTime($arr[$k+1]['date']))->diff($d)->days;
        if ($diff > 1) {
            $result = array_merge($result , array_map(function($v) use($d){
                $d_copy = clone $d;
                return [
                    'date' => $d_copy->add(new DateInterval('P' . $v. 'D'))->format('Y-m-d'),
                    'total' => 0
                ];
            }, range(1, $diff-1)));
        }
    }
}

print_r($result);

The output:

Array
(
    [0] => Array
        (
            [date] => 2017-09-01
            [total] => 4
        )

    [1] => Array
        (
            [date] => 2017-09-02
            [total] => 0
        )

    [2] => Array
        (
            [date] => 2017-09-03
            [total] => 0
        )

    [3] => Array
        (
            [date] => 2017-09-04
            [total] => 0
        )

    [4] => Array
        (
            [date] => 2017-09-05
            [total] => 0
        )

    [5] => Array
        (
            [date] => 2017-09-06
            [total] => 0
        )

    [6] => Array
        (
            [date] => 2017-09-07
            [total] => 6
        )

    [7] => Array
        (
            [date] => 2017-09-08
            [total] => 0
        )

    [8] => Array
        (
            [date] => 2017-09-09
            [total] => 7
        )
)

#2


1  

Here I create new arrays as reference.
One for all dates from first item in your array to last (range).
And one array with only the dates from your array so that I can search it.
This should handle more than one missing date and multiple missing dates.

在这里,我创建新的数组作为参考。一个适用于所有日期,从数组中的第一个项目到最后一个(范围)。一个数组只包含数组中的日期,以便我可以搜索它。这应该处理多个丢失日期和多个丢失日期。

$arr = array (
  0=>array(
    'date'=>'2017-09-01',
    'total'=>4
  ),
  1=>array(
    'date'=>'2017-09-07',
    'total'=>6
  )
);
// array with only dates to search in
$dates = array_column($arr, "date"); 

// Create an array with all dates from first item to last item
$start = new DateTime($arr[0]["date"]);
$end = new DateTime(end($arr)["date"]);

$range = new DatePeriod($start, new DateInterval('P1D'), $end);
// $range is now all dates from start to end minus last one.  

// Loop through the range 
foreach($range as $date){
    //See if the current date exist is first array
    $find = array_search($date->format("Y-m-d"), $dates);
    If($find !== false){
         $result[] = $arr[$find]; // if it does copy it to result array
    }Else{
         // If not add it and create a total = 0
         $result[] = array('date' => $date->format("Y-m-d"), 'total' => 0);
    }
}
// Since the loop does not loop all dates we need to add the last item to result.
$result[] = end($arr);
Var_dump($result);

https://3v4l.org/Hf73Z
Edit; forgot date ->format()

https://3v4l.org/Hf73Z编辑;忘了日期 - >格式()

#3


0  

Using an if statement try this :

使用if语句试试这个:

foreach($array as $ar){
if(!$ar["date"]){
 $ar["date"] = date("j- n- Y"); ;
 }
}