【问题标题】:How to search for a value in a sub array and get to know the key index of that sub array如何在子数组中搜索值并了解该子数组的键索引
【发布时间】:2014-07-16 05:42:43
【问题描述】:

我有一个具有这种结构的数组:

$months = array(
     MM => array(
         'start' => DD, 
         'end'   => DD,
         'type'  => (string),
         'amount'=> (float),
      ),
 );

MM 是一个月(01-12,字符串),DD 是一个月中的一天(01-31,字符串)。 并非所有月份都在数组中。对于每个月,都有可变数量的子数组,每个子数组的范围都有唯一的天数。例如,一个月有三个子数组,三个范围的天,但这些范围内使用的天永远不会重叠或重复,每个 DD 值都是唯一的。唯一的例外是在某些范围内“开始”和“结束”可能重合(同一个 DD 日),但每个月永远不会有两个相同的“开始”日或两个相同的“结束”日。

我需要在每个月循环几个月和几天时使用这个数组。在本月的每一天循环时,我需要检查该特定日期是否在“开始”或“结束”中匹配。如果匹配为真,我还需要检索相邻的值。

在这样做的过程中我遇到了一个问题:我如何知道存在这种匹配的子数组的键索引?例如,我如何知道比赛是否开启

$months['09'][3]['start'] == $current_day_in_loop;

或者更确切地说:

$months['09'][6]['start'] == $current_day_in_loop;

还是另一个键?

由于我不知道每个月有多少范围,因此索引键是可变的,或者可能根本没有。如何查找匹配值是否在键[3][6] 上?一旦我知道密钥,我就可以使用它来查找同一子数组中的相邻值。

【问题讨论】:

  • 不知道你想在哪里使用这个结构
  • 这是一种日历,我需要为每个月存储可变数量的天数 - 不考虑年份;如果有充分的理由,我可能会更改数组的结构
  • 好吧,您可以使用 php 的 date() time() 函数轻松实现这一点。为什么明确需要这种特殊类型的结构?我的意思是,既然轮子已经存在,为什么还要重新发明呢?
  • 我不需要时间戳,我需要从这些数据中提取数年。与现在时间无关。是否有任何 php 函数可以帮助我建立日期范围?此外,稍后我还需要在 javascript 对象中使用相同的数组数据。
  • date() 以您自己的自定义格式转换任何日期字符串或时间戳。如果你不想要几年,那很好。建立日期范围是可能的。如果您在 php 中获取值,那么很容易将其传输到 JS 变量。

标签: php multidimensional-array key-value arrays


【解决方案1】:

您可以执行过滤器来确定匹配的日期:

$matches = array_filter($months['09'], function($item) use ($current_day_in_loop) {
    return $item['start'] == $current_day_in_loop;
});
// if $matches is empty, there were no matches, etc.
foreach ($matches as $index => $item) {
    // $months['09'][$index] is the item as well
}

【讨论】:

    【解决方案2】:

    请尝试使用以下示例获取密钥:

    //loop start
        if (($key = array_search($searchedVal, $dataArr)) !== false) {
            echo $key;
        }
    // loop end
    

    【讨论】:

    • 如果$dataArr 的每个元素都是一个标量,这将起作用,但在这种情况下,它包含数组。
    【解决方案3】:

    如果匹配为真,我还需要检索相邻的值。在此过程中,我遇到了一个问题:我如何了解 有这种匹配的子数组的键索引?例如,如何 我知道比赛是否正在进行

    如果我理解正确,您遇到的主要问题是您想要检索匹配项的下一个和上一个元素,但不知道如何检索,因为您不知道键是什么。

    您可以通过 next

    遍历数组来实现此目的
    $months = array(
         '01' => array(
             'start' => '1', 
             'end'   => '31',
             'type'  => 'hello',
             'amount'=> 2.3,
          ),
         '02' => array(
             'start' => '2', 
             'end'   => '31',
             'type'  => 'best',
             'amount'=> 2.5,
          ),
         '03' => array(
             'start' => '3', 
             'end'   => '31',
             'type'  => 'test',
             'amount'=> 2.4,
          ),       
     );
    
    $matches = array();
    $prev = null;
    $prev_key = null;
    $key = key($months);
    $month = reset($months);
    
    while($month) {
    
        $next = next($months);
        $next_key = key($months);
    
        foreach(range(1,31) as $current_day_in_loop) {
            //if end or start match grab the current, previous and next values
            if($month['start'] == $current_day_in_loop
            || $month['end'] == $current_day_in_loop) {
                $matches[$key] = $month;
    
                if($prev)
                    $matches[$prev_key] = $prev;
    
                if($next)
                    $matches[$next_key] = $next;
            }
        }
    
        $prev = $month;
        $prev_key = $key;
        $month = $next;
        $key = $next_key;
    }
    
    print_r($matches);
    

    【讨论】:

    • 这是正确的,但不幸的是,在我的情况下,无论是否有 $months,我都处于一年中每个月的 for 循环中;当我需要获取范围时,我已经在子 for 循环中循环了几天,而其中的“foreach”我只能检查是否有匹配项。不过谢谢,它很有用。
    猜你喜欢
    • 2021-04-09
    • 2012-11-14
    • 1970-01-01
    • 2014-05-20
    • 2012-03-05
    • 2017-10-29
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    相关资源
    最近更新 更多