Arc Forumnew | comments | leaders | submitlogin
Can you suppress the "nil" returning on iteration function ?
1 point by thaddeus 5851 days ago | 9 comments
I've created one function that iterates over a table, and returns a correct results, but as with all iteration functions, it's followed by nil.

A second function takes the results from the above function, but I get an error:

"list-ref: expects type <non-negative exact integer> as 2nd argument, given: nil;...."

I am assuming the 'nil' is being passed in as well...when it shouldn't be..

Can I suppress this? Thanks, T.



1 point by thaddeus 5851 days ago | link

; i'll skip the code that loads the tables from files.... here's the results ; arc> (vals ktable) ; ((0 "FIRST") (1 "MIDDLE") (2 "LAST")) ; arc> (vals dtable) ; (("Jon" "Mid" "Dow") ("Jane" "Moodd" "Meow") ("Alex" "Morse" "Lstname"))

    (def dkey (at-name)
	    (for i 0 (- (len ktable) 1)
            (if (is ((ktable i) 1) at-name)
			(prn i)))) 
			
    ; arc> (dkey "MIDDLE")
    ; 1
    ; nil


    ; ((dtable "Jane" ) 1) .... this works passing in '1' but if I substitue for the dkey function i get the error
    ; arc> ((dtable "Jane" ) 1)
    ; "Moodd"


    (def at-val (dat-name at-name)
        ((dtable dat-name) (dkey at-name)))

     ; so  (at-val "Jane" "MIDDLE") generated the error

-----

1 point by skenney26 5851 days ago | link

Maybe it would be simpler to use a list for your data structure:

  (= names* '(("Jon" "Mid" "Dow") ("Alex" "Morse" "Lstname") ("Jane" "Moodd" "Meow")))
Then you could use 'assoc to find a name:

  arc> (assoc "Jane" names*)
  ("Jane" "Moodd" "Meow")
And integers to return the first, middle, and last parts of a name:

  arc> ((assoc "Jane" names*) 1)
  "Moodd"

-----

1 point by thaddeus 5851 days ago | link

I think your code looks much cleaner, but I guess I have a few more points/questions.

1. Using the assoc function I would still have pass in a number to find the value for a given attribute a user chooses, correct? Which means I still would have to write an iteration function to find the position of that value to return and then would run into the same problem.

2. I have an assumption that when working with large volumes of data one would want to use a table, and small volumes should use a list....Is this correct? (my example above is only for testing)...

Thanks, T.

-----

1 point by rincewind 5851 days ago | link

What do you want to do with these data structures exactly?

Something like this?

  (= names* 
    (obj person1 '("Jon" "Mid" "Dow")
         person2 '("Alex" "Morse" "Lstname") 
         person3 '("Jane" "Moodd" "Meow")))

  (def get-name-part (person part)
       ((names* person) ((obj first 0 middle 1 last 2) part)))

-----

1 point by thaddeus 5851 days ago | link

I've have to check the code at home, at work now.....

Essentially I'm taking a spreadsheet file (csv) with an arbitrary number of columns of data, reading in the headers so they can be output to the html table as headers then reading in the remainder to create rows in the html table.

also also letting users to pick and choose which columns of data they want by selecting header names.

I've pretty much got it all working, I'm just surprised the language wouldn't provide for passing in results of an iteration function cleanly. To have to create an extra function simply to strip out the nil ends up making the code readability poor..... I'm sure I will look at the code in 2 months, scratch my head and ask why I needed a second function.... of course by then I'll probably have found a better way :)

-----

1 point by rincewind 5850 days ago | link

  (def keep-cols (cols tabl) ;for one row
     (map [let nr -1 (keep [some (++ nr) cols] _)] tabl))

  (def get-cols (cols tabl) ;table with selected columns
      (withs ((head . rows) tabl
              colnrs (rem nil (map [pos _ head] cols))
              filtered-rows (keep-cols colnrs rows))
        (cons cols filtered-rows)))

  ;test
  (get-cols '(foo baz) '((foo bar baz) ;header
                         (bla bla spam)
                         (eggs ham bacon) 
                         (lorem ipsum test)))

-----

1 point by thaddeus 5849 days ago | link

That's much nicer code than mine :)

I'm going to step through some of the syntax; I haven't been using: map, [], or "." yet.

Thanks, T.

-----

1 point by thaddeus 5851 days ago | link

Kinda found a way to do it - though it kinda seems strange to have to use this approach.

    (def at-id-val (dat-name at-name)
       (for i 0 (- (len ktable) 1)
         (if (is ((ktable i) 1) at-name)     
               (pr ((dtable dat-name) i)))
       ))

    (def at-val (dat-name at-name)
      (tostring (at-id-val dat-name at-name))
     )
T.

-----

1 point by skenney26 5851 days ago | link

Could you provide the code that you have so far?

-----