1

Let's say I have a list of integers, representing year, month, day for a date:

(2017 8 21)

and I want to format the list in one function call, as in

(format "%04d-%02d-%02d" 2017 8 21)

Is there an easy way to do this? I know I could assign the list to a variable and use elt to extract each element, but I'm hoping for a simpler solution.

(I really want to get YYYY-MM-DD for the first day of a given iso week, and has gotten so far as to that (math-date-to-dt (math-parse-iso-date (format "%04dW%02d1" year week))) will give me above mentioned list.)

Drew
  • 75,699
  • 9
  • 109
  • 225
Niclas Börlin
  • 618
  • 5
  • 15

3 Answers3

5

You can use the apply function to pass a function arguments contained in a list as separate arguments. For example:

(apply #'format "%04d-%02d-%02d" '(2017 8 21))

That way you can store the list in a variable or compute it with a function call, etc.

(let ((best-day-ever '(2017 8 21)))
  (apply #'format "%04d-%02d-%02d" best-day-ever))
Omar
  • 4,732
  • 1
  • 17
  • 32
2

Just for fun and profit:

(destructuring-bind (year month day) '(2017 8 21)
  (format "%04d-%02d-%02d" year month day))

An unfortunate use of eval:

(eval `(format "%04d-%02d-%02d" ,@ '(2017 8 21)))

A macro form of that:

(defmacro dformat (date)
  `(format "%04d-%02d-%02d" ,@date))

(dformat (2017 8 21))
John Kitchin
  • 11,555
  • 1
  • 19
  • 41
1

Following is a way to apply a list of arguments to a function, which I believe is what you need:

(let ((x '(2017 8 21))
      (f (lambda(x y z) (format "%04d-%02d-%02d" x y z ))))
  (apply f x))

apply applies a list of arguments to a given function.

Juancho
  • 5,395
  • 15
  • 20
  • Note that `apply` takes an arbitrary number of arguments, and only the last is a *list* of arguments, so there's no need for an anonymous function (see Omar's answer). – phils Aug 23 '17 at 00:57