Hello,
Inspired by this thread:
http://www.newlispfanclub.alh.net/forum/viewtopic.php?f=16&t=4918&p=24159&hilit=csv#p24159
Using the artful-newlisp-master/csv.lsp I get a proper list.
The first sublist contains the column header names.
Now I want to transform the list to a assoc-list where the column header names get inserted in each other line as a assoc-key:
So ("Colname1" "Colname2" ....)
and
Lines (Val1 Val2 ....)
gets
(("Colname1" Val1)("Colname2" Val2) ...)
What is the shortest/best approach?
Regards
Hans-Peter
Oops,
To early this morning. I think this will do the job.
> (map list '(1 2 3) '(4 5 6))
((1 4) (2 5) (3 6))
Regards
Hello,
My first approach:
(load "C:/Programme/newlisp/artful-newlisp-master/csv.lsp")
(setq csvlst(CSV:parse-file "C:/Programme/newlisp/csv_file.csv" ","))
(setq colnames (first csvlst))
(setq csvlst (rest csvlst))
(setq alst (list ))
(dolist (sublst csvlst)
(setq alst(append alst (list(map list colnames sublst))))
)
Any better?
Rergards
someting like:
(set 'csv '(("a" "b") (1 2) (3 4) (5 6)))
(flat (map (fn(x) (map list (first csv) x)) (rest csv)) 1)
=> (("a" 1) ("b" 2) ("a" 3) ("b" 4) ("a" 5) ("b" 6))
Thanks for the code-sample.
But instead of your result:
(("a" 1) ("b" 2) ("a" 3) ("b" 4) ("a" 5) ("b" 6))
I want:
((("a" 1) ("b" 2)) (("a" 3) ("b" 4)) (("a" 5) ("b" 6)))
Regards
HPW, just use fdb's code but remove the outer call to flat. That will get you what you want, i.e., "rows".
Hello rickyboy,
Thanks for the hint. Works like a charm.
Regards
Hello,
And finally when I need the assoc list into symbols:
(map (fn (x) (set(sym(first x))(last x)))assoclst)
Regards
Quote from: "HPW"
And finally when I need the assoc list into symbols:
(map (fn (x) (set(sym(first x))(last x)))assoclst)
HPW,
With the above, you caused me to have a crazy thought. Make a macro that does `let`-type bindings for you, given an assoc list; then, you could write any code under that `let` to do more computations. Having a form of a `let` keeps the bindings local (i.e., does not pollute your top-level).
Here's the macro. (Notice that I'm using your idea to make the bindings.)
(define-macro (let-alist [alist])
(letex ([bindings]
(map (fn (b) (list (sym (b 0)) (b 1)))
(letex ([alist] [alist]) [alist]))
[body]
(cons 'begin (args)))
(let [bindings] [body])))
Now, a simple usage: list `a` and `b` and their sum.
(let-alist '(("a" 3) ("b" 4))
(list a b (+ a b)))
--> (3 4 7)
Here's a more complex usage: find the sum and average of the `a` and `b` columns.
(let (asum 0 bsum 0 N 0)
(dolist (alist (csv->alists csv))
(let-alist alist
(inc asum a)
(inc bsum b))
(inc N))
(list 'asum asum 'aavg (div asum N)
'bsum bsum 'bavg (div bsum N)))
--> (asum 9 aavg 3 bsum 12 bavg 4)
Of course, `csv` is fdb's example:
(set 'csv '(("a" "b") (1 2) (3 4) (5 6)))
And the `csv->alists` function is just fdb's solution to your problem.
(define (csv->alists csv)
(map (fn (x) (map list (first csv) x))
(rest csv)))
There might be a simpler way. Please let me know if you find one! Cheers. --Rick
Hello rickyboy,
Yes, crazy but also cool. With this powerfull functions from newlisp I found the code harder to read and understand, but thats the power and beauty of newlisp. Thanks for sharing your ideas.
Regards