4
$\begingroup$

How to remove 0 that represent hours, minutes, and seconds from a date list say a

 a = {{{2007, 1, 3, 0, 0, 0.}, 10.}, {{2007, 1, 4, 0, 0, 0.},20.}, {{2007, 1, 5, 0, 0, 0.}, 30.}}

Result should be:

{{{2007, 1, 3}, 10.}, {{2007, 1, 4},20.}, {{2007, 1, 5}, 30.}}
$\endgroup$
3
  • $\begingroup$ One possible solution: b = a /. {x_, y_, z_, i_, j_, k_} -> {x, y, z} though you would need to be careful when you have exactly 6 temporal datum $\endgroup$
    – Jonie
    Commented Dec 3, 2014 at 10:30
  • 1
    $\begingroup$ {#[[1, 1 ;; 3]], #[[2]]} & /@ a $\endgroup$
    – Yves Klett
    Commented Dec 3, 2014 at 10:59
  • $\begingroup$ This should delete all "0" and "0." elements from your List: b = Delete[a, Position[a, n_ /; Or[n==0,n==0.]]]. $\endgroup$
    – Boson
    Commented Dec 3, 2014 at 11:29

6 Answers 6

6
$\begingroup$
a = {{{2007, 1, 3, 0, 0, 0.}, 10.}, {{2007, 1, 4, 0, 0, 0.},  20.},
     {{2007, 1, 5, 0, 0, 0.}, 30.}};

{#[[;; 3]], #2} & @@@ a
(* {{{2007,1,3},10.}, {{2007,1,4},20.}, {{2007,1,5},3 0.}} *)
$\endgroup$
4
$\begingroup$
Cases[a, {x_, y_} :> {x[[;; 3]], y}]
$\endgroup$
4
$\begingroup$

With ReplaceAt (since V 13.1)

a = {{{2007, 1, 3, 0, 0, 0.}, 10.}, {{2007, 1, 4, 0, 0, 0.}, 20.}, {{2007, 1, 5, 0, 0, 0.}, 30.}};

ReplaceAt[_ :> Nothing, {All, 1, 4 ;;}] @ a

{{{2007, 1, 3}, 10.}, {{2007, 1, 4}, 20.}, {{2007, 1, 5}, 30.}}

Or

MapAt[Nothing, {All, 1, 4 ;;}] @ a

(same result)

$\endgroup$
0
3
$\begingroup$

Here is an alternative aiming at maximal robustness: it does only change those entries of the list for which the change makes sense (i.e. the first part looks like a date list). Of course other approaches are much more efficient, so if efficiency is relevant and you know that all entries look the same, this approach is probably not what you want to use...

Replace[a, 
  {date : {Repeated[_?NumericQ, {6}]}, value_} :> {Take[date, 3],value}, 
  {1}
]

note that by restricting the pattern to exactly 6 repetitions we don't have a problem if there are cases where the date lists have only 1 or 2 elements. By restricting Replace to only work on the 1st level we also don't run into the problem that the list itself could be matched (or any subexpression at a deeper level)...

$\endgroup$
3
$\begingroup$

I find Part the easist way of doing this sort of operation:

a[[All, 1]] = a[[All, 1, 1 ;; 3]];
a

(* {{{2007, 1, 3}, 10.}, {{2007, 1, 4}, 20.}, {{2007, 1, 5}, 30.}} *)
$\endgroup$
3
$\begingroup$

Using DateObject: (introduced {2014, 7, 9})

Since dates are being handled, choosing granularity as "Day" can filter the hours, minutes and seconds.

a = {{{2007, 1, 3, 0, 0, 0.}, 10.}, {{2007, 1, 4, 0, 0, 0.}, 
   20.}, {{2007, 1, 5, 0, 0, 0.}, 30.}}

f = DateObject[#, "Day"][[1]] &

MapAt[f, a, {All, 1}]

{{{2007, 1, 3}, 10.}, {{2007, 1, 4}, 20.}, {{2007, 1, 5}, 30.}}


Example:

With granularity set to "Month":

g = DateObject[#, "Month"][[1]] &
MapAt[g, a, {All, 1}]

{{{2007, 1}, 10.}, {{2007, 1}, 20.}, {{2007, 1}, 30.}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.