alternative indexing in nth

Started by cormullion, December 03, 2006, 09:18:22 AM

Previous topic - Next topic

Lutz

#15
this will work:


(define (get-index idx lst)
    (ref ((flat lst) idx) lst))

(get-index 3 '(a b (c d e))) => (2 1)


Lutz



ps: there is no 'car' in newLISP, do you probably mean 'first'.

cormullion

#16
There is a way to get the syntax i want using this macro, but i'd prefer to post it anonymously, it's so horrible: :-)


(set 'lst (list (list 1 2 3) (list 'a 'b 'c)))
(set 'a-ref (ref 'a lst))

(define-macro (my-nth _aref _l)
(local (_n0 _n1 _n2 _n3 _n4 _n5 _n6 _n7 _n8 _n9)
(set '_n0 (nth 0 (eval _aref)))
(set '_n1 (nth 1 (eval _aref)))
(set '_n2 (nth 2 (eval _aref)))
(set '_n3 (nth 3 (eval _aref)))
(set '_n4 (nth 4 (eval _aref)))
(set '_n5 (nth 5 (eval _aref)))
(set '_n6 (nth 6 (eval _aref)))
(set '_n7 (nth 7 (eval _aref)))
(set '_n8 (nth 8 (eval _aref)))
(set '_n9 (nth 9 (eval _aref)))
(nth _n0 _n1 _n2 _n3 _n4 _n5 _n6 _n7 _n8 _n9 (eval _l))))

(lst a-ref)
;-> a
(my-nth a-ref lst)
;-> a


I know what you're thinking - it only works up to 10 levels... !

Lutz

#17
there is a shorter way ;)
(define-macro (my-nth _ref _lst)
    (eval (cons 'nth (append  (eval _ref)  (list _lst)))))

(my-nth a-ref lst) => a

or written in a hygienic fashion:
(define-macro (my-nth)
    (eval (cons 'nth (append  (eval (args 0))  (list (args 1))))))

(my-nth a-ref lst) => a

Lutz

cormullion

#18
There had to be a better way, and thanks for showing it to me! :-) Sometimes my 'simplistic' approach doesn't yield the best answer...

nikus80

#19
True, but get-index doesn't work with duplicated items.

Of course that didn't seem to be an issue, but that's why I went the hard way. I got it working now.


(define (get-index ind lst (current 0))
  (if (not (list? lst)) '()
    (let (len (get-flat-length (first lst)))
       (if (> ind (- len 1))
          (get-index (- ind len) (rest lst) (+ 1 current))
          (cons current (get-index ind (first lst)))))))

(define (get-flat-length lst)
  (cond
        ((null? lst) 0)
        ((list? lst) (+ (get-flat-length (first lst)) (get-flat-length (rest lst))))
        (true 1)))
         
(define-macro (flat-nth-set ind lst ele)
    (eval (append '(nth-set) (get-index ind (eval lst)) (list lst) (list ele))))


Sorry if any of you read the previous code, it was awful.

BTW I wasn't happy with the catch-dolist-throw pattern. Plain recursion seems shorter to me.

Lutz

#20
you can define 'get-flat-length' much shorter using the built-in 'flat':


(define (get-flat-length lst)
    (length (flat lst))))


also, I don't understand what you mean with:
QuoteTrue, but get-index doesn't work with duplicated items.


Can you give an example where your defintion of 'get-index' works different from this one?


(define (get-index idx lst)
    (ref ((flat lst) idx) lst))


Lutz

nikus80

#21
yes.



yours:

> (get-index 6 '(a b (c d e) f a))

(0)



mine:



> (get-index 6 '(a b (c d e) f a))

(4)



I wanted get flat length to return 1 on atoms, so it's more like:

(define (get-flat-length lst)

    (if (list? lst) (length (flat lst)) 1))