Jump to content

Get index of all occurrences of element in list - for fun


Recommended Posts

Posted (edited)

Here you have my two propositions:

(defun PosLst_1 ( l e / p r )
 (setq p 0)
 (foreach % l
   (if (= e %)
     (setq r (cons p r))
   )
   (setq p (1+ p))
 )
 (reverse r)
)
(defun PosLst_2 ( l e / p r )
 (while (setq p (vl-position e l))
   (setq 
     r (cons (if r (+ 1 p (car r)) p) r)
     l (cdr (member e l))
   )
 )
 (reverse r)
)

(PosLst_1 '("a" "d" "b" "c" "d" "e" "f" "d") "d")
(1 4 7)
(PosLst_2 '("a" "d" "b" "c" "d" "e" "f" "d") "d")
(1 4 7)

 

What are your ideas?

Edited by ziele_o2k
Grrr good point: BTW why you use in PosLst_1 '(nth p l)', when you can just use '%' ?
Posted (edited)

Hi ziele,

 

(defun _ItemPositions1 ( L itm / i )
 (setq i -1)
 (apply 'append
   (mapcar 
     (function 
       (lambda (x)
         (setq i (1+ i))
         (if (eq itm x)
           (list i)
         )
       )
     )
     L
   )
 )
)

 

(defun _ItemPositions2 ( L itm )
 (
   (lambda (f) (f L itm 0))
   (lambda ( L itm i )
     (if L
       (append
         (if (eq (car L) itm) (list i) ) 
         (f (cdr L) itm (1+ i))
       )
     )
   )
 )
)

 

(defun _ItemPositions3 ( L itm / i r )
 (setq i -1) (setq L (cons nil L))
 (while (progn (setq i (1+ i)) (setq L (cdr L)))
   (and (eq itm (car L)) (setq r (cons i r)))
 )
 (reverse r)
)

 

(defun _ItemPositions4 ( L itm / i r )
 (repeat (setq i (length L))
   (if (eq itm (nth (setq i (1- i)) L)) (setq r (cons i r)))
 )
 r
)

 

(defun _ItemPositions5 ( L itm )
 ( (lambda (f) (reverse (f (reverse L) itm)))
   (lambda ( L itm )
     (if L
       (append
         (if (eq (car L) itm) (list (1- (length L))) ) 
         (f (cdr L) itm)
       )
     )
   )  
 )
)

 

BTW why you use in PosLst_1 '(nth p l)', when you can just use '%' ?

I like your approach in PosLst_2, with member I'd write it like so:

 

(defun _ItemPositions6 ( L itm )
 (
   (lambda ( L itm / b r )
     (setq b (and L (= ([b][color="red"]last[/color][/b] L) itm)))
     (while (setq L (cdr (member itm L)))
       (setq r (cons (length L) r))
     )
     (if b (cons 0 r) r)
   )
   (reverse L) itm
 )  
)

Edited by Grrr
Posted
(defun position-p (lst itm / n l)
 (setq n 0)
 (while lst
   (and (= (car lst) itm)
        (setq l (cons n l))
   )
   (setq lst (cdr lst)
         n   (1+ n)
   )
 )
 (reverse l)
)

Posted
(defun pos (l e / f)
 (defun f (l e n)
   (if l
     (if
       (= (car l) e)
       (cons n (f (cdr l) e (1+ n)))
       (f (cdr l) e (1+ n))
     )
   )
 )
 (f l e 0)
)

Posted
(defun indexes ( x l / n r )
   (setq n (length l))
   (while (setq l (member x l))
       (setq r (cons (- n (length l)) r)
             l (cdr l)
       )
   )
   (reverse r)
)

Posted
_$ (_ItemPositions6 '(0 1 0 1 0 1) 1)
(0 1 3 5)

 

Thanks for the remark, Lee!

Corrected: car must be last. :geek:

 

 

See other solutions here

 

Nice, more suggestions for the collection! :)

Posted

another but not generic, for number & string only

(defun foo ( l i)
(mapcar 'cdr (vl-remove-if-not ''((x)(= (car x) i)) (mapcar 'cons (vl-sort l '<) (vl-sort-i l '< )  ) ) ) )

 

 

(foo l "d")
(7 4 1)

Posted

:idea: Nice one hanhphuc, by checking your suggestion, you've lightened the bulb in my head:

 

(defun PositionsForEach ( L / groupbykey )
 (defun groupbykey ( lst / rtn tmp ) ; Lee Mac
   (foreach itm (reverse lst)
     (if (setq tmp (assoc (car itm) rtn))
       (setq rtn (subst (vl-list* (car itm) (cdr itm) (cdr tmp)) tmp rtn))
       (setq rtn (cons  (list (car itm) (cdr itm)) rtn))
     )
   )
 )
 (if L
   (reverse (groupbykey (mapcar 'cons (vl-sort l '>) (vl-sort-i l '>) )))
 )
)

 

_$ (PositionsForEach '("d" "e" "a" "c" "d" "a" "b" "c" "d" "e" "f" "d"))
>> (("a" 5 2) ("b" 6) ("c" 7 3) ("d" 11 8 4 0) ("e" 9 1) ("f" 10))

Posted (edited)
:idea: Nice one hanhphuc, by checking your suggestion, you've lightened the bulb in my head:

 

_$ (PositionsForEach '("d" "e" "a" "c" "d" "a" "b" "c" "d" "e" "f" "d"))
>> (("a" 5 2) ("b" 6) ("c" 7 3) ("d" 11 8 4 0) ("e" 9 1) ("f" 10))

 

no worries, that's advantage of visual lisp :)

 

i was thinking recursive but thanks Stefan is smarter

[code
(defun _ItemPositions1
(defun _ItemPositions2
(defun _ItemPositions3
(defun _ItemPositions4
(defun _ItemPositions5
[/code]
[/quote]
nice many examples with recursive too, good afford!

another
[color="green"];PositionsForEach [/color]

(defun pos ( ls / lst l)
(setq lst (mapcar 'cons (vl-sort ls '>) (vl-sort-i ls '>) ) )
 (mapcar ''((a) (cons (caar a) (mapcar 'cdr a))) 
  (LM:Unique (foreach a	(mapcar 'car lst)
	       (setq l (cons (vl-remove-if-not ''((x) (= a (car x))) lst) l))
	       ) 
	     ) 
  ) 
 )
[color="green"]
;; Unique  -  Lee Mac
;; Returns a list with duplicate elements removed.[/color]
(defun LM:Unique ( l )
   (if l (cons (car l) (LM:Unique (vl-remove (car l) (cdr l)))))
)

 

(setq ls '("d" "e" "a" "c" "d" "a" "b" "c" "d" "e" "f" "d"))

(pos ls)
(("a" 5 2) ("b" 6) ("c" 7 3) ("d" 11 8 4 0) ("e" 9 1) ("f" 10)) 

Edited by hanhphuc
Posted

nice many examples with recursive too, good afford!

 

Thanks, it was fun thinking of how many ways there would be to write such subfoo.

But didn't thought about the ones from theswamp (Stefan's link) and especially the suggestions from Lee (there).

Usually if I needed such subfoo - I'd write quickly something like the '_ItemPositions1', rather than digging into my LISP archive.

 

another

 

I'm not very aware of your coding, but you seem very good at list manipulations! :thumbsup:

I think these last subfunctions provide ultimate return: with that returned assoc list one could reconstruct completely the original one.

Also it just requires (cdr (assoc ..)) to retrieve the positions of .

Theres just one drawback: no listp items. :glare:

Posted

Thank you all for your ideas. I started this thread to open my mind for other solutions.

Here is my third proposition:

(defun PosLst_3 ( l e / n p r)
 (setq n -1)
 (while
   (and
     (setq p (vl-position e l))
     (setq n (+ 1 n p)
           r (cons n r)
           l (cdr (member e l))
     )
   )
 )
 (reverse r)
)

Because I like to add to my library those functions which work as fast as possible I made some benchmark.

Elapsed milliseconds / relative speed for 8192 iteration(s):

   (POSLST_3 LST 4).............1891 / 50.32 <fastest>
   (POSLST_2 LST 4).............2000 / 47.58
   (INDEXES LST 4)..............3719 / 25.59
   (_ITEMPOSITIONS6 LST 4)......4531 / 21
   (POSLST_1 LST 4).............4562 / 20.86
   (_ITEMPOSITIONS3 LST 4)......4718 / 20.17
   (POSITION-P LST 4)...........4718 / 20.17
   (POS LST 4)..................5297 / 17.96
   (_ITEMPOSITIONS1 LST 4)......5828 / 16.33
   (_ITEMPOSITIONS4 LST 4).....16875 / 5.64
   (_ITEMPOSITIONS5 LST 4).....92484 / 1.03
   (_ITEMPOSITIONS2 LST 4).....95157 / 1 <slowest>

(...)

BTW why you use in PosLst_1 '(nth p l)', when you can just use '%' ?

(...)

overlook

Posted
Last one :)

(defun PosLst_4 ( l e / p r )
 (setq p -1)
 (while (setq p (vl-position e l))
   (setq 
     r (cons (+ 1 p) r)
     l (cdr (member e l))
   )
 )
 (reverse r)
)

I don't see how this one can work properly.

Posted
I don't see how this one can work properly.

yep, I deleted post. Time to sleep :)

Posted
.

Theres just one drawback: no listp items. :glare:

As mentioned in post#9 not generic only for number & string due to vl-sort can't compare listp ;)

 

i'm just same as you joined in 2013, but most of the skills inspired by Lee, Tharwat etc..

Now you are better than me because you put more afford in practice, as you can see Lee has +20k of posts imagine how much he practiced - thats why as you mentioned before Leesp Macnipulator ;)

Posted

Because I like to add to my library those functions which work as fast as possible I made some benchmark.

Elapsed milliseconds / relative speed for 8192 iteration(s):

   (POSLST_3 LST 4).............1891 / 50.32 <fastest>
   (POSLST_2 LST 4).............2000 / 47.58
   (INDEXES LST 4)..............3719 / 25.59
   (_ITEMPOSITIONS6 LST 4)......4531 / 21
   (POSLST_1 LST 4).............4562 / 20.86
   (_ITEMPOSITIONS3 LST 4)......4718 / 20.17
   (POSITION-P LST 4)...........4718 / 20.17
   (POS LST 4)..................5297 / 17.96
   (_ITEMPOSITIONS1 LST 4)......5828 / 16.33
   (_ITEMPOSITIONS4 LST 4).....16875 / 5.64
   (_ITEMPOSITIONS5 LST 4).....92484 / 1.03
   (_ITEMPOSITIONS2 LST 4).....95157 / 1 <slowest>

 

overlook

Thanks :thumbsup:

Posted

i'm just same as you joined in 2013, but most of the skills inspired by Lee, Tharwat etc..

 

Well, the first few years from my joining date were posts that were related to begging for a lisp routines... and not so much about learning. :lol:

 

 

Now you are better than me because you put more afford in practice,

 

Its true that I practice almost everyday, but you can't say that someone's better than the other!

 

To share why I'm thinking so:

You know.. once when I studied about the 'symboltables' I found a subfunction by Michael Puckett (I didn't knew who he was) :

;; Written By Michael Puckett.
(defun Table (s / d r) 
 (while (setq d (tblnext s (null d))) (setq r (cons (cdr (assoc 2 d)) r)) ) 
)
(Table "layer")

Few months passed, but I kept thinking why that guy copyrighted such simple subfunction.

So I thought he has to be some newbie/medium level LISPer and all that time I underestimated him.

But later I joined the forum he is still active.. and boy he blew my brains off!

Sometimes he writes an overwhelming solutions for me, where I don't have the brain capacity to understand them.

So just use the offered copyrighted subfoo, while I'm still far from understanding its algorithm.

 

As for Lee,

I always thought hes far ahead of everyone.. (and I still think so)

So with my every code attempt I kept the thought "can I even impress this guy with some of my codes?"

Then I realised how experienced he is, so perhaps the answer was 'no'.. so my next thought was "can I get close to his skill?"

So I learned/practiced, but the thing was everytime I ask about something on the forums - and he answers,

he reveals how much he knows about the subject.. so instead of thinking that I'm getting closer I realise how much stuff I didn't knew about!

So this guy is like the Universe: the more you ask him, the more he reveals, and the more you know how much you don't know. :lol:

..and the more scary he becomes (his knowledge).

 

If you feel on the top of LISP, and think theres nothing else to learn -

just check my created topics at theswamp (and you'll see why I came up with the List Manipulator pun), or try to revise fragments of Lee's programs. :)

 

 

Lee has +20k of posts imagine how much he practiced

 

I don't think the amount of posts strictly relate to the practice level of one (neither the time he spent on the forums),

I've seen ziele's other posts and hes far good at LISP, Stefan has some scary skills aswell, same as Rlx, Roy also seems far experienced,

although they all have relatively small count of posts comparing to their skills.

And I think that applies to you aswell, maybe the reason is experience from native lisp forums?

 

But to draw the bottom line: never underestimate anyone! ;)

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...