Reputation: 128
Given the following array:
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' ];
I need it grouped by year then month then day so that my final result is something like this:
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"] )
)
In the end I will auto populate a MM/DD/YYYY drop downs. So if a user selects year 2012 the following month drop down value is only 10 followed by the day drop down which would only have 01, 02, 03. If they select 2011 the following month drop down would only say 01, 06. If they select 01 then the following days would only be 01 or 02.
Hope that didnt confuse anyone and the question is clear. Multidimensional arrays are the worst I know.
Ideally Id like to do this in Javascript but PHP is ok too. One array in, one array out.
Upvotes: 1
Views: 687
Reputation: 16472
_.map(list, iterator, [context]) Alias: collect
Produces a new array of values by mapping each value in list through a transformation function (iterator). If the native map method exists, it will be used instead. If list is a JavaScript object, iterator's arguments will be (value, key, list)._.reduce(list, iterator, memo, [context]) Aliases: inject, foldl
Also known as inject and foldl, reduce boils down a list of values into a single value. Memo is the initial state of the reduction, and each successive step of it should be returned by iterator.
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"
]
}
}
Upvotes: 2
Reputation: 21249
This would do it:
$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);
Output:
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)
Upvotes: 3
Reputation: 35797
First, you parse all the date strings out in to their separate parts. Then, you iterate through those parts, and put them in to the appropriate arrays.
(A very general answer for a very general question.)
Upvotes: 0