1

给定以下数组:

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 也可以。一进一出。

4

3 回答 3

3

这会做到:

$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)
于 2012-07-10T01:25:23.843 回答
2

使用Underscore.js

_.map (list, iterator, [context])别名collect
通过转换函数(迭代器)映射列表中的每个值来生成一个新的值数组。如果存在原生 map 方法,则会使用它。如果 list 是 JavaScript 对象,迭代器的参数将是 (value, key, list)。

_.reduce (list, iterator, memo, [context])别名inject , foldl
也称为 inject 和 foldl,reduce 将值列表归结为单个值。备忘录是归约的初始状态,它的每一步都应该由迭代器返回。

例子:

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"
      ]
   }
}
于 2012-07-10T01:36:24.050 回答
0

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

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

于 2012-07-10T01:20:16.053 回答