If I have a CSV file (with no header) that contains three columns and I want to return values of the second column as a list, how is the best method to do that?
I have seen something where one can separate a string into a list by a divider (in my case, the commas between the three columns) but the actual code for me to inspect was supposed to be in an attached ZIP file which I didn't see as part of the post.
An example of my CSV (as a list) wouild be:
("PO-30-10,PIN OAK,88-15" "PO-30-10,PIN OAK,88-01A" "JS-20-5,JUNIPER,63-04" "PP-40-10,POPLAR,38-22")
and I need the resulting list to be:
("PIN OAK" "PIN OAK" JUNIPER" "POPLAR")
Is there a LISP way to do this - or only VLISP?
~Mia
Mia
Here ia a way.
(setq xx '("PO-30-10,PIN OAK,88-15" "PO-30-10,PIN OAK,88-01A" "JS-20-5,JUNIPER,63-04" "PP-40-10,POPLAR,38-22"))
(foreach n xx
(setq a (vl-string-position (ascii ",") n))
(setq b (substr n (+ a 2)))
(setq c (vl-string-position (ascii ",") b))
(setq d (substr b 1 c))
(setq vv (append vv (list d)))
)
("PIN OAK" "PIN OAK" "JUNIPER" "POPLAR")
hth
HYG
(defun second (str / func str) (setq func (lambda (j) (substr j 1 (vl-string-position 44 j))) str (substr str (+ (strlen (func str)) 2)) str (func str) ) )
(mapcar 'second '("PO-30-10,PIN OAK,88-15" "PO-30-10,PIN OAK,88-01A" "JS-20-5,JUNIPER,63-04" "PP-40-10,POPLAR,38-22"))
Perhaps it would be better if you stripped the string right after the read-line
(while (Setq x (read-line fl))
(setq lst (cons (second x) lst))
)
Do you really need a vanilla version of the code?
A Generic code (Vanilla)
(defun secondV (j n / x a b c i) (setq a "" b (lambda ()(substr j 2)) i 0) (while (and (wcmatch j "*`,*") (setq x (ascii j)) (> n i)) (if (eq x 44) (setq c a a "" j (b) i (1+ i)) (setq a (strcat a (chr x)) j (b)))) (if (> n i) j c ))
(Setq a "JS-20-5,JUNIPER,63-04")
(secondV a 1)
hth"JS-20-5"
(secondV a 2)
"JUNIPER"
(secondV a 3)
"63-04"
(setq lst '("PO-30-10,PIN OAK,88-15" "PO-30-10,PIN OAK,88-01A" "JS-20-5,JUNIPER,63-04" "PP-40-10,POPLAR,38-22"))
(mapcar '(lambda (r)(secondV r 1)) lst)
("PO-30-10" "PO-30-10" "JS-20-5" "PP-40-10")
(mapcar '(lambda (r)(secondV r 2)) lst)
("PIN OAK" "PIN OAK" "JUNIPER" "POPLAR")
(mapcar '(lambda (r)(secondV r 3)) lst)
("88-15" "88-01A" "63-04" "38-22")
HTH
@CAD-a-Mia wrote:If I have a CSV file (with no header) that contains three columns and I want to return values of the second column as a list, how is the best method to do that?
(defun csv-second-column (path separator) ;; produces a list of the items in the second column of a csv file. Separator as a single-character string. (mapcar '(lambda (line) (cadr (split-string line separator))) (file-to-list path))) (defun split-string (str delim / pos) ;; Splits a string into a list of strings at every occurrence of the delim (single-letter string). (setq pos (vl-string-position (ascii delim) str)) (if (null pos) (list str) (cons (substr str 1 pos) (split-string (substr str (+ pos 2)) delim)))) (defun file-to-list (filename / file result line) (if (findfile filename) (progn (setq file (open filename "r")) (while (setq line (read-line file)) (setq result (cons line result))) (close file) (reverse result)) (alert (strcat "File " filename " not found!"))))
--
FWIW: VL code for delimiter separator
(defun _delFinder (str md / d l str) (while (setq d (vl-string-position md str nil T)) (setq l (cons (substr str (+ 2 d)) l) str (substr str 1 d))) (cons str l) )
HTH