【问题标题】:Group multidimensional array分组多维数组
【发布时间】:2012-07-09 10:56:27
【问题描述】:

给定以下数组:

var dates = ['2012-10-01', '2012-10-02', '2012-10-03', '2011-01-01', '2011-01-02', '2011-06-03', '2010-09-01', '2010-09-02', '2010-08-22' ];

我需要按年、月、日分组,这样我的最终结果是这样的:

Array (
   "2012" => 
       Array ( "10" => Array ["01", "02", "03"] )

   "2011" =>
       Array ( "01" => Array ["01", "02"] )
       Array ( "06" => Array ["03"] )

   "2010" =>
       Array ( "09" => Array ["01", "02"] )
       Array ( "08" => Array ["22"] )
)

最后,我将自动填充 MM/DD/YYYY 下拉列表。因此,如果用户选择 2012 年,则下个月的下拉值只有 10,然后是只有 01、02、03 的天下拉值。如果他们选择 2011 年,下个月的下拉值只会显示 01、06。如果他们选择 01 则接下来的日子只会是 01 或 02。​​

希望这不会使任何人感到困惑,并且问题很清楚。多维数组是我所知道的最糟糕的。

理想情况下,我喜欢在 Javascript 中执行此操作,但 PHP 也可以。一进一出。

【问题讨论】:

  • 到目前为止你尝试过什么?这不是“怎么做”,这是“帮助我因为问题而被困”的地方

标签: php javascript arrays multidimensional-array


【解决方案1】:

这样就可以了:

$dates = array('2012-10-01', '2012-10-02', '2012-10-03', '2011-01-01', '2011-01-02', '2011-06-03', '2010-09-01', '2010-09-02', '2010-08-22');

$out = array();

foreach($dates as $date)
{
    $parts = explode('-',$date);

    if (!isset( $out[$parts[0]] ))
        $out[$parts[0]] = array();

    if (!isset( $out[$parts[0]] [$parts[1]] ))
        $out[$parts[0]] [$parts[1]] = array();

    if (!in_array($parts[2], $out[$parts[0]] [$parts[1]] )) 
        $out[$parts[0]] [$parts[1]] [] = $parts[2];
}

var_dump($out);

输出:

array
  2012 => 
    array
      10 => 
        array
          0 => string '01' (length=2)
          1 => string '02' (length=2)
          2 => string '03' (length=2)
  2011 => 
    array
      '01' => 
        array
          0 => string '01' (length=2)
          1 => string '02' (length=2)
      '06' => 
        array
          0 => string '03' (length=2)
  2010 => 
    array
      '09' => 
        array
          0 => string '01' (length=2)
          1 => string '02' (length=2)
      '08' => 
        array
          0 => string '22' (length=2)

【讨论】:

    【解决方案2】:

    使用Underscore.js

    _.map(list, iterator, [context]) 别名收集
    通过转换映射列表中的每个值来生成新的值数组 函数(迭代器)。如果原生 map 方法存在,将被使用 反而。如果 list 是 JavaScript 对象,迭代器的参数将是 (值、键、列表)。

    _.reduce(list, iterator, memo, [context]) 别名: inject, foldl
    也称为注入和折叠,reduce 将值列表归结为 单值。备忘录是还原的初始状态,每个 它的后续步骤应该由迭代器返回。

    Example:

    var dates = ['2012-10-01', '2012-10-02', '2012-10-03', '2011-01-01', '2011-01-02', '2011-06-03', '2010-09-01', '2010-09-02', '2010-08-22' ];
    _.chain(dates)
        .map(function(date){ return date.split('-'); })
        .reduce(function(memo, num){ 
            if(!memo[num[0]]){ memo[num[0]] = {}; }
            if(!memo[num[0]][num[1]]){ memo[num[0]][num[1]] = []; }
            memo[num[0]][num[1]].push(num[2]);
            return memo;
        }, {})
        .tap(function(curVal){ alert(JSON.stringify(curVal)); })
    
    //Produces
    ​{
       "2010":{
          "09":[
             "01",
             "02"
          ],
          "08":[
             "22"
          ]
       },
       "2011":{
          "01":[
             "01",
             "02"
          ],
          "06":[
             "03"
          ]
       },
       "2012":{
          "10":[
             "01",
             "02",
             "03"
          ]
       }
    }
    

    【讨论】:

    • 谢谢,但我现在不想使用外部库。然而,这将是最好的前端解决方案。
    【解决方案3】:

    首先,您将所有日期字符串解析为单独的部分。然后,您遍历这些部分,并将它们放入适当的数组中。

    (一个非常笼统的问题的非常笼统的答案。)

    【讨论】:

      猜你喜欢
      • 2023-04-06
      • 2010-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-02
      • 2021-03-30
      相关资源
      最近更新 更多