csv to assoc-list

Q&A's, tips, howto's

csv to assoc-list

Postby HPW » Fri Jan 25, 2019 7:06 am

Hello,

Inspired by this thread:
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
Hans-Peter
HPW
 
Posts: 1364
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany

Re: csv to assoc-list

Postby HPW » Fri Jan 25, 2019 7:13 am

Oops,

To early this morning. I think this will do the job.

Code: Select all
> (map list '(1 2 3) '(4 5 6))
((1 4) (2 5) (3 6))


Regards
Hans-Peter
HPW
 
Posts: 1364
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany

Re: csv to assoc-list

Postby HPW » Fri Jan 25, 2019 7:38 am

Hello,

My first approach:
Code: Select all
(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
Hans-Peter
HPW
 
Posts: 1364
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany

Re: csv to assoc-list

Postby fdb » Fri Jan 25, 2019 9:11 pm

someting like:
Code: Select all
(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))
fdb
 
Posts: 39
Joined: Sat Nov 09, 2013 8:49 pm

Re: csv to assoc-list

Postby HPW » Sat Jan 26, 2019 5:29 am

Thanks for the code-sample.
But instead of your result:
Code: Select all
(("a" 1) ("b" 2) ("a" 3) ("b" 4) ("a" 5) ("b" 6))

I want:
Code: Select all
((("a" 1) ("b" 2)) (("a" 3) ("b" 4)) (("a" 5) ("b" 6)))

Regards
Hans-Peter
HPW
 
Posts: 1364
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany

Re: csv to assoc-list

Postby rickyboy » Sat Jan 26, 2019 6:58 am

HPW, just use fdb’s code but remove the outer call to flat. That will get you what you want, i.e., “rows”.
(λx. x x) (λx. x x)
rickyboy
 
Posts: 556
Joined: Fri Apr 08, 2005 7:13 pm
Location: Front Royal, Virginia

Re: csv to assoc-list

Postby HPW » Sat Jan 26, 2019 12:21 pm

Hello rickyboy,

Thanks for the hint. Works like a charm.

Regards
Hans-Peter
HPW
 
Posts: 1364
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany

Re: csv to assoc-list

Postby HPW » Sun Jan 27, 2019 9:03 am

Hello,

And finally when I need the assoc list into symbols:

Code: Select all
(map (fn (x) (set(sym(first x))(last x)))assoclst)


Regards
Hans-Peter
HPW
 
Posts: 1364
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany

Re: csv to assoc-list

Postby rickyboy » Mon Jan 28, 2019 12:32 am

HPW wrote:And finally when I need the assoc list into symbols:

Code: Select all
(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.)

Code: Select all
(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.

Code: Select all
(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.

Code: Select all
(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:

Code: Select all
(set 'csv '(("a" "b") (1 2) (3 4) (5 6)))

And the `csv->alists` function is just fdb's solution to your problem.

Code: Select all
(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
(λx. x x) (λx. x x)
rickyboy
 
Posts: 556
Joined: Fri Apr 08, 2005 7:13 pm
Location: Front Royal, Virginia

Re: csv to assoc-list

Postby HPW » Mon Jan 28, 2019 5:31 pm

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
Hans-Peter
HPW
 
Posts: 1364
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany


Return to newLISP in the real world

Who is online

Users browsing this forum: No registered users and 2 guests

cron