将多个 CodeIgniter 结果集合并到一个数组中

Merge multiple CodeIgniter result sets into one array

从数据库中查询到数据。

year 2021 = [
    {
        "month": 1,
        "total": "1,482"
    },
    {
        "month": 2,
        "total": "5,422"
    },
]

year 2020 = [
    {
        "month": 1,
        "total": "2,482"
    },
    {
        "month": 2,
        "total": "6,422"
    },
    {
        "month": 3,
        "total": "7,422"
    },
    .........
    {
        "month": 12,
        "total": "20,422"
    },
]

在这里我创建了一个名为 `GetData() 的方法,我根据一年中的月份创建了一个从 1-12 的循环。接下来我想合并一个数组中的数据,但是如何合并数据呢?

下面是我的控制器模型,它使用不同的参数一遍又一遍地调用相同的模型方法:

public function GetData(){
    $thn_now = 2021; 
    $thn_before = 2020; 
    $bulan = array();
    for ($bul = 1; $bul <= 12; $bul++) {
        $sql = $this->My_model->model_month($bul,$thn_now)->result();  // Here I make the current year parameter
        // $sql2 = $this->My_model->model_month($bul,$thn_before)->result();  //here are the parameters of the previous year
        foreach($sql as $row) {
            $bulan[] = array(
                'bulan' => $bul,
                'total_now' => $row->hasil,
                // how to display the previous year's total in an array ?
                // 'total_before' => $row->hasil,
            );
        }
    }
    $this->set_response($bulan,200);  
}

我想要这样的输出:

[
    {
        "month": 1,
        "total_now": "1,482"
        "total_before": "2,482"
    },
    {
        "month": 2,
        "total_now": "5,522"
        "total_before": "6,422"
    },
    {
        "month": 3,
        "total_now": null 
        "total_before": "7,422"
    },
    .........
    {
        "month": 12,
        "total_now": null,
        "total_before": "20,422"
    },
]

2021年总数只到02月,而2020年总数到12月

如果 2021 年仅到 02 月,则下一个数组总计 null

我相信这将有助于您开发解决方案。我没有包括 $year_2020 的整个数组,但我希望你能理解 -

$year_2021 = [
   [
    "month" => 1,
    "total_now" => "1,482"
   ],
   [
    "month" => 2,
    "total_now" => "5,422"
   ]
  ];

  $year_2020 = [
   [
    "month" => 1,
    "total_before" => "2,482"
   ],
   [
    "month" => 2,
    "total_before" => "6,422"
   ],
   [
    "month" => 3,
    "total_before" => "7,422"
   ]
  ];

  $output = [];

  foreach ($year_2021 as $obj) {
     $key = $obj['month'];
     $output[$key] = $obj;
  }

 foreach ($year_2020 as $obj) {
    $key = $obj['month'];
    if (isset($output[$key])) {
      $output[$key]['total_before'] = $obj['total_before'];
    } else {
      $obj['total_now'] = null;
      $output[$key] = $obj;
    }
   }

    $output = array_values($output);
    error_log(json_encode($output));

输出

[{"month":1,"total_now":"1,482","total_before":"2,482"},{"month":2,"total_now":"5,422","total_before":"6,422"},{"month":3,"total_before":"7,422","total_now":null}]
  1. 我不建议您访问数据库 24 次以收集个人总计;我会敦促您创建一个新的模型方法,在单次旅行中提供所有月度总计。
  2. 我不建议让您的控制器指定从模型中的活动记录创建的结果集的类型。在整个应用程序中,模型应该始终以相同的结构返回相同的数据。
  3. 在我看来你的内部循环无论如何只收集一行,所以不是 result() 创建一个对象数组,而是调用 row() 创建 null 或然后立即访问一个对象 hasil 属性。使用空合并运算符,当 hasil 不是非对象 null.
  4. 的 属性 时,您可以回退到 null
  5. 世界各地的专业程序员(包括那些不以英语为第一语言的程序员)都会推荐使用英文单词编写变量。这可以让其他开发人员使用更一致的语言来审查和维护您的代码。毕竟,你在其余的 php 语法中使用英语,只需将其全部使用英语即可。
  6. 为了将来的灵活性,允许将“当前年份”作为控制器方法参数传入。这将使您能够无缝查看历史数据(如果需要)。如果没有传入参数,则默认为当前年份。
  7. 硬编码每个月的数字是可以接受的,因为它永远不会改变。但是,作为一般规则,请尽量避免在您的脚本中使用硬编码 numbers/values,这样它会更灵活、更易于维护并且更直观易读。

建议的代码(允许您将最多 24 个活动记录对象传递回控制器):

public function GetMonthlyTotalsSincePreviousYear($year = null): void
{
    $thisYear = $year ?? date('Y');
    $lastYear = $thisYear - 1;
    $result = [];
    for ($month = 1; $month <= 12; ++$month) {
        $result[] = [
            'month' => $month,
            'total_now' => $this->My_model->model_month($month, $thisYear)->row()->hasil ?? null,
            'total_before' => $this->My_model->model_month($month, $lastYear)->row()->hasil ?? null,
        ];
    }
     $this->set_response($result, 200);  
}

在我自己的应用程序中,我会有一个收集所有数据的模型方法和一个控制器,如下所示:

public function getMonthlyTotalsSincePreviousYear(int $year = null): void
{
    $this->set_response(
        $this->My_model->getMonthlyTotalsSincePreviousYear($year ?? date('Y')),
        200
    );
}