【问题标题】:PHP: Increment a variable based on change in another variable in foreach loopPHP:根据foreach循环中另一个变量的变化增加一个变量
【发布时间】:2018-10-09 17:08:27
【问题描述】:

我有一个 foreach 循环,用于打印我的应用程序中订单项更改的历史记录。每个订单项都有一个编号,每个订单项可以有多个更改。

我想要做的是在我的循环执行时在每次更改旁边显示行号。 $i 将保存行号。

$i = 1;
foreach($lineItem as $line) {
   echo $i; //line number
   echo $line['field_changed'];
   echo $line['change_date'];
   echo $line['change_from'];
   echo $line['change_to'];
}

代码从名为line_item_changes 的数据库表中读取,结构如下:

id  line_id  parent_id
--  -------  ---------
1   2401     521
2   2401     521
3   2401     521
4   2500     521
5   2502     521
6   2502     521  

每当$line['line_id'] 中的值发生变化时,我都想增加$i。因此,当结果显示时,它们看起来像这样:

Line #: 1
field: notes
date: 10/9/2018
from: test
to: test2

Line #: 1
field: quantity
date: 10/1/2018
from: 4
to: 3

Line #: 2
field: need_date
date: 10/1/2018
from: 10/24/2018
to: 10/27/2018

等等

【问题讨论】:

  • 您能提供更多信息吗?据我了解,您有一个表line_item_changes 并循环遍历它,当line_id 更改时,您希望$i 增加,对吗?当您循环通过line_item_changes 时会出现这样的结果吗?: 第一个循环:1 - 2401(没有变化),然后是2 - 2401(没有变化),然后是3 - 2401(没有变化),然后是4 - 2500(@987654335 @ 已更改,$i 将递增)。
  • 是的,没错。 $i 应在每次 line_id 更改时增加 1。所以前三个更改 (2401) 将是第 1 行 ($i = 1),2500 将是第 2 行 ($i = 2),等等。

标签: php cakephp-2.0 cakephp-2.1


【解决方案1】:

只需将之前的line_id 存储在一个变量中,如果值发生变化,则更新$i。尝试以下操作(代码 cmets 中的解释):

$i = 1;
$prev_line_id = null; // initializing the previous value

foreach($lineItem as $line) {

   // if the previous line_id exists
   if (isset($prev_line_id)) {

       // if previous value does not match with the current value
       if ($prev_line_id != $line['line_id']) {

           // increment the line number
           $i++;
       }
   }

   // set the previous value
   $prev_line_id = $line['line_id'];

   echo $i; //line number
   echo $line['field_changed'];
   echo $line['change_date'];
   echo $line['change_from'];
   echo $line['change_to'];
}

注意,您可以直接从 DB 查询本身获取更改的行号。你可以使用像Dense_Rank()这样的窗口函数。

【讨论】:

  • 您应该在增加$i 后将$prev_line_id 设置为$line['line_id']。如果你不这样做,当两个具有相同line_idlineItems 在循环中相继出现时,$i 将递增。
  • @JeroenGroenveld 事实上我将先前值的设置移到循环之外,我们现在只需要检查先前值是否匹配,并相应地增加 $i。
  • 编辑后的工作就像一个魅力。非常感谢。完美的解决方案。
  • @Chris 很乐意提供帮助 :) 您也可以考虑查看 dense_rank() 并直接从 DB 本身获取此行号。
  • @Chris MySQL version >= 8.0 确实支持它。您的版本可能是 5+ 。反正是可以模仿的。检查我的答案之一:stackoverflow.com/a/52352996/2469308 这会给你一些想法。你可以创建一个新问题,你肯定会得到你的 MySQL 版本的答案
【解决方案2】:

你必须存储最后一个循环的最后一个line_id,然后用下一个循环的line_id检查它,如果它们不相等则增加$i,当$i增加你设置@ 987654325@到当前line_id

$prev_line_id = $lineItem[0]['line_id'] ?? null;
$i = 0;
foreach($lineItem  as $line)
{
    if($line['line_id'] != $prev_line_id )
    {
        $i++;
        $prev_line_id = $line['line_id'];
    }

    echo $i; //line number
    echo $line['field_changed'];
    echo $line['change_date'];
    echo $line['change_from'];
    echo $line['change_to'];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    相关资源
    最近更新 更多