William James <w_a_x_man@yahoo.com> wrote:
+---------------
| Lars Rune N�stdal wrote:
| > ..and yes; Common Lisp is way better that both Java, Perl,
| > Python or Ruby. Try it out, and you'll see why. :)
|
| Really? Then this problem should be utterly trivial for you.
| A file contains lines like
| 06-Jul.14:10 .....
| 06-Jul.09:58 .....
| 13-Jun.09:27 .....
| Sort them by date and time.
+---------------
Perhaps not *utterly* trivial, but it's fairly simple all the same: ;-}
> (defun my-parse-time (string)
;; Some mimimal error checking
(loop for (c i) in '((#\- 2) (#\. 6) (#\: 9) (#\space 12))
unless (eql c (char string i))
do (error "Bad punctuation in input string: ~s" string))
;; Could use a hash table, but the list *is* quite short
(let* ((months '("Jan" "Feb" "Mar" "Apr" "May" "Jun"
"Jul" "Aug" "Sep" "Oct" "Nov" "Dec"))
(month (position (subseq string 3 6) months :test #'equalp))
(date (parse-integer string :end 2))
(hour (parse-integer string :start 7 :end 9))
(minute (parse-integer string :start 10 :end 12)))
(unless month
(error "Bad month format in input string: ~s" string))
;; This result doesn't have to be the correct year, just monotonic
(encode-universal-time 0 minute hour date month 2006)))
MY-PARSE-TIME
> (let ((lines (list "06-Jul.14:10 ....."
"06-Jul.09:58 ....."
"13-Jun.09:27 .....")))
(format t "~{~s~%~}" (sort lines #'< :key 'my-parse-time))
(values)) ; [suppress printing the value]
"13-Jun.09:27 ....."
"06-Jul.09:58 ....."
"06-Jul.14:10 ....."
>
And if you insist on the lines really being in a file first, and
being printed without the quotes around them, then:
> (with-open-file (s "foo.txt")
(let ((lines (loop for line = (read-line s nil nil)
while line
collect line)))
(format t "~{~a~%~}" (sort lines #'< :key 'my-parse-time))
(values)))
13-Jun.09:27 .....
06-Jul.09:58 .....
06-Jul.14:10 .....
>
If you want the result to go into another file, we can do that too:
> (with-open-file (in "foo.txt")
(with-open-file (out "foo.out" :direction :output
:if-exists :supersede)
(let ((lines (loop for line = (read-line in nil nil)
while line
collect line)))
(format out "~{~a~%~}" (sort lines #'< :key 'my-parse-time)))))
NIL
> (quit)
$ cat foo.out
13-Jun.09:27 .....
06-Jul.09:58 .....
06-Jul.14:10 .....
$
-Rob
p.s. Note: The values-suppression trick is non-standard, but works
in a number of CL implementations [CMUCL & CLISP, for two].
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607