Jinsong Zhao <
jsz...@yeah.net> writes:
> On 2014/4/9 9:20, Dimitri Fontaine wrote:
>> Jinsong Zhao <
jsz...@yeah.net> writes:
>>> Thanks a lot for the lazy method. However, I have to read the necessary
>>> lines from file. I don't know how to join all the read-in lines together.
>>
>> Transform each line to a vector and keep counting elements separately,
>> it should be easy enough right?
>>
>
> Yes, it easy enough. In fact, in the final code, I used your method.
>
> I'm not a loop lover. I just don't know how to do that using mapping
> mechanism.
>
>> Damn. So here's the code I came up with, for loop lovers:
>>
>> (defpackage #:jszhao
>> (:use cl))
>>
>> (in-package #:jszhao)
>>
>> (defparameter *contents* "
>> -38.18381 -26.49595 -18.00396 -15.52326 -15.51745 -12.46277
>> -11.13900 3.50872 3.89552 4.22668 4.38951 5.64658
>> 1.90757 0.94853 2.31361 2.76930 2.31454 0.00000
>> ")
>>
>
> I the previous post, I wanted to say the above lines is saved in a
> file, I should read it out. Thus I have to read each line out by a
> loop (or something else??). So I have to joint the lines together, and
> then use your method to deal with it.
>> (defun read-pair-from (content index &aux (target (- index 1)))
>> "CONTENT is expected to be a string maybe spanning more than one line and
>> containing whitespace separated numbers. Read numbers at indexes INDEX
>> and INDEX+1, considering that INDEX should start at 1."
>> (with-input-from-string (s content)
>> (loop
>> :for start := 0 :then (+ start len)
>> :for line := (read-line s nil nil)
>> :while line
>> :for vector := (read-line-into-vector line)
>> :for len := (length vector)
>>
>> :when (<= start target (+ start len -1))
>> :collect (aref-offset vector target start)
>>
>> :when (<= start (+ target 1) (+ start len -1))
>> :collect (aref-offset vector (+ target 1) start))))
1- notice that CL I/O functions are still used. Instead of reading
from the string you can read directly from a file if you wish so.
2- in any case a function should only perform one task. Opening a file
(or a string) and parsing a file are TWO different functions. This
read-pair-from needs refactoring anyways.
3- in any case, you should not use random code without understanding
what it does. For example, there's a bug in the following function:
>> (defun read-line-into-vector (line)
>> "Parse a LINE string containing whitespace separated numbers as a vector
>> of numbers, and return that number."
>> (let ((clean-line (string-trim '(#\Space #\Return #\Tab) line)))
>> (when clean-line
>> (read-from-string (format nil "#(~a)" clean-line)))))
3- and since it doesn't perform any I/O it shouldn't be named READ-…
anyways.
>> (defun aref-offset (vector index offset)
>> "Consider that the given VECTOR actually starts at OFFSET rather than 0
>> and return its value at this INDEX."
>> (aref vector (- index offset)))
(defun parse-line-into-vector (line)
"Parse a LINE string containing whitespace separated numbers as a vector
of numbers, and return that vector of numbers."
(let ((clean-line (string-trim '(#\Space #\Return #\Tab) line)))
(when (and clean-line (plusp (length line)))
(read-from-string (format nil "#(~a)" clean-line)))))
(defun aref-offset (vector index offset)
"Consider that the given VECTOR actually starts at OFFSET rather than 0
and return its value at this INDEX."
(aref vector (- index offset)))
(defun read-pair-from (stream index &aux (target (- index 1)))
"CONTENT is expected to be a string maybe spanning more than one line and
containing whitespace separated numbers. Read numbers at indexes INDEX
and INDEX+1, considering that INDEX should start at 1."
(loop
:for start := 0 :then (+ start len)
:for line := (read-line stream nil nil)
:while line
:for vector := (parse-line-into-vector line)
:for len := (length vector)
:when (<= start target (+ start len -1))
:collect (aref-offset vector target start)
:when (<= start (+ target 1) (+ start len -1))
:collect (aref-offset vector (+ target 1) start)))
(with-input-from-string (stream *contents*)
(read-pair-from stream 6))
--> (-12.46277 -11.139)
(with-open-file (stream "/tmp/contents")
(read-pair-from stream 6))
--> (-12.46277 -11.139)
>>
>> JSZHAO> (read-pair-from *contents* 6)
>> (-12.46277 -11.139)
>>
>> HTH,
--
__Pascal Bourguignon__
http://www.informatimago.com/
"Le mercure monte ? C'est le moment d'acheter !"