Author Topic: [challenge]: Get Next/Previous List Item  (Read 868 times)

0 Members and 1 Guest are viewing this topic.

cmwade77

  • Swamp Rat
  • Posts: 1361
[challenge]: Get Next/Previous List Item
« on: March 08, 2022, 11:51:38 AM »
Create a function that will get the next item after a specified value. It should get the first item if the specified value is the last item in the list. Likewise, there should be an option to get previous value and if the current value is the first value in the list, it should go back to the end of the list.

EXAMPLES:
(setq TestList (list "$Object - Yes" "$Object - No" "$Box" "$Loop" "$Spline" "$None"))

(GetNextValue TestList "$Box")
Returns: "$Loop"

(GetNextValue TestList "$None")
Returns: "$Object - Yes"

(GetPreviousValue TestList "$Object - Yes")
Returns: "$None"

(GetPreviousValue TestList "$Loop")
Returns: "$Box"



Here is my version:
Code: [Select]
;Chris Wade - cmwade77 - theswamp.org
(defun GetNextValue (ListVar Value / Ct)
  (setq Ct (FindInList ListVar Value))
  (if (= (+ Ct 1) (length ListVar))
    (setq Ct 0)
    (setq Ct (+ Ct 1))
  )
  (nth Ct ListVar)
)

(defun GetPreviousValue (ListVar Value / Ct)
  (setq Ct (FindInList ListVar Value))
  (if (< (- Ct 1) 0)
    (setq Ct (length ListVar))
    (setq Ct (- Ct 1))
  )
  (nth Ct ListVar)
)

(defun FindInList (ListVar Value / Ct Result)
  (setq Ct -1)
  (while (< Ct (length ListVar))
    (setq Ct (+ Ct 1))
    (if (= (nth Ct ListVar) Value)
      (setq Result Ct
            Ct (length ListVar)
      )
    )
  )
  (if (not Result)
    (setq Result -1)
  )
  Result
)
« Last Edit: March 08, 2022, 12:19:29 PM by cmwade77 »

JohnK

  • Administrator
  • Seagull
  • Posts: 10140
Re: [challenge]: Get Next List Item
« Reply #1 on: March 08, 2022, 12:02:34 PM »
Code - Auto/Visual Lisp: [Select]
  1. (defun nextitem (lst item)
  2.   (if (equal item (last lst))
  3.     (car lst)
  4.     (if lst
  5.       (if (equal (car lst) item)
  6.         (cadr lst)
  7.         (nextitem (cdr lst) item)))))

Should be redesigned but typed up quickly.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

ronjonp

  • Needs a day job
  • Posts: 7437
Re: [challenge]: Get Next/Previous List Item
« Reply #2 on: March 08, 2022, 12:34:47 PM »
Quick one to get next and previous
Code - Auto/Visual Lisp: [Select]
  1. (defun _getnext-rjp (l i / a)
  2.   (if (setq a (member i l))
  3.     (if (= 1 (length a))
  4.       (car l)
  5.       (cadr a)
  6.     )
  7.   )
  8. )
  9. (defun _getprevious-rjp (l i / a)
  10.   (if (setq a (member i (setq l (reverse l))))
  11.     (if (= 1 (length a))
  12.       (car l)
  13.       (cadr a)
  14.     )
  15.   )
  16. )
« Last Edit: March 08, 2022, 12:41:55 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2022

Custom Build PC

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1314
  • Marco
Re: [challenge]: Get Next/Previous List Item
« Reply #3 on: March 08, 2022, 12:36:11 PM »
...similar
Code: [Select]
(defun GetNextValue (L x / n)
  (if (setq n (cdr (member x L)))
    (car n)
    (car L)
  )
)

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1314
  • Marco
Re: [challenge]: Get Next/Previous List Item
« Reply #4 on: March 08, 2022, 12:49:07 PM »
Code: [Select]
(defun GetPreviousValue_Ale (L x / p)
  (if (zerop (setq p (vl-position x L)))
    (last L)
    (nth (1- p) L)
  )
)

kirby

  • Newt
  • Posts: 110
Re: [challenge]: Get Next/Previous List Item
« Reply #5 on: March 08, 2022, 05:40:20 PM »
One more...

Code - Auto/Visual Lisp: [Select]
  1. (defun C:TestGNP ( / TestList TestVals CNT MyVals MyItem MyOpt Ans)
  2. ; Test function for 'GetAdjacent-kirby'
  3.  
  4. (setq TestList (list "$Object - Yes" "$Object - No" "$Box" "$Loop" "$Spline" "$None"))
  5. (prompt "\nTest List = ")(princ TestList)(princ)
  6.  
  7. (setq TestVals (list
  8.         '("$Box" 1)             ; $Loop
  9.         '("$None" 1)            ; $Object - Yes
  10.         '("Cat" 1)              ; (not in list)
  11.         '("$Object - Yes" -1)   ; $None
  12.         '("$Loop" -1)           ; $Box
  13.         '("Dog" -1)             ; (not in list)
  14. ))
  15.  
  16. (setq CNT 0)
  17. (repeat (length TestVals)
  18.         (setq MyVals (nth CNT TestVals))
  19.         (setq MyItem (nth 0 MyVals) MyOpt (nth 1 MyVals))
  20.        
  21.         (setq Ans (GetAdjacent-kirby TestList MyItem MyOpt))
  22.        
  23.         (prompt "\n  Item = '")(princ MyItem)(prompt "'  Option = ")(princ MyOpt)
  24.         (prompt "  --> '")(princ Ans)(prompt "' ")(princ)
  25.        
  26.         (setq CNT (1+ CNT))
  27. ) ; close repeat
  28. )
  29.        
  30. (defun GetAdjacent-kirby (MyList MyItem RelPos / L MyPos NewPos OutVal)
  31. ; Challenge 2022-03-08 - Get Next/Previous List Item
  32. ; Input:
  33. ;       MyList - (list) a list of strings or numbers (or lists)
  34. ;       Item - (varies) item of interest from list
  35. ;       RelPos - (integer) code -1 = return previous item, 1 or nil = return next item
  36. ; Returns:
  37. ;       Returns adjacent item in list, or nil if not found.
  38. ;       list assumed to be 'wrapped' so next item last item in list returns first item in list, etc.
  39. ; Uses custom functions:
  40. ;       FindListPos
  41.  
  42.  
  43. ; defaults
  44. (if (not RelPos) (setq RelPos 1))
  45.  
  46. (setq OutVal nil)
  47.  
  48. (if (eq (type MyList) 'LIST)
  49.   (progn
  50.         (setq L (length MyList))
  51.  
  52.         ; Find position of item (returns nil if not found)
  53.         (setq NewPos (FindListPos MyList MyItem))
  54.  
  55.         (if NewPos
  56.           (progn
  57.                 ; Get new index of desired item using integer math trickery
  58.                 (setq NewPos (+ RelPos NewPos))
  59.        
  60.                 ; Correct overflow
  61.                 (if (> NewPos (1- L)) (setq NewPos (- NewPos L)))
  62.                
  63.                 ; Correct underflow
  64.                 (if (< NewPos 0) (setq NewPos (+ NewPos L)))
  65.        
  66.                 ; Get and return adjecent item
  67.                 (setq OutVal (nth NewPos MyList))
  68.           )
  69.         ) ; close if
  70.   )
  71. ) ; close if
  72. OutVal
  73. )
  74.  
  75.  
  76. (defun FindListPos (MyList MyItem / OutVal CNT k CurItem)
  77. ; Find position of an item in a list
  78. ; Input:
  79. ;       MyList - (list) a list of unique items
  80. ;       Item - (varies) item of interest from list
  81. ; Returns:
  82. ;       Adjacent item in list, or nil if not found.
  83. ;       list assumed to be 'wrapped' so next item last item in list returns first item in list, etc.
  84.  
  85. (setq OutVal nil)
  86.  
  87. (if (member MyItem MyList)
  88.   (progn
  89.         (setq CNT 0)
  90.         (setq k 1)
  91.         (while k
  92.                 (setq CurItem (nth CNT MyList))
  93.                 (if (eq CurItem MyItem)
  94.                         (setq OutVal CNT k nil) ; found item, stop loop
  95.                 ) ; close if
  96.                
  97.                 (setq CNT (1+ CNT))
  98.                
  99.                 (if (> CNT (length MyList))
  100.                         (setq k nil)            ; out of data, stop loop
  101.                 )
  102.         ) ; close while
  103.   )
  104. ) ; close if
  105. OutVal
  106. )
  107.  

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1314
  • Marco
Re: [challenge]: Get Next/Previous List Item
« Reply #6 on: March 09, 2022, 10:50:07 AM »
Vl version
Code: [Select]
(defun GetNextValue_Ale (L x / p)
  (if (setq p (nth (1+ (vl-position x L)) L))
    p
    (car L)
  )
)

pBe

  • Bull Frog
  • Posts: 401
Re: [challenge]: Get Next/Previous List Item
« Reply #7 on: March 09, 2022, 12:27:29 PM »
Code - Auto/Visual Lisp: [Select]
  1. (defun GetNextValue (l s)
  2.   (cadr (member s (cons (last l) l)))
  3.   )

_$ (GetNextValue TestList "$Box")
"$Loop"
_$ (GetNextValue (reverse TestList) "$Box")
"$Object - No"

Otherwise
Code - Auto/Visual Lisp: [Select]
  1. (defun GetPreviousValue (l s)
  2.   (setq l (reverse l))
  3.   (cadr (member s (cons (last l) l)))
  4. )

« Last Edit: March 09, 2022, 12:34:04 PM by pBe »


Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1314
  • Marco
Re: [challenge]: Get Next/Previous List Item
« Reply #9 on: March 10, 2022, 03:09:42 AM »
Code - Auto/Visual Lisp: [Select]
  1. (defun GetNextValue (l s)
  2.   (cadr (member s (cons (last l) l)))
  3.   )
   :yes: :)
Code: [Select]
(setq TestList '(0 1 2 3 4 5 6 7 8 9 0))
(progn (foreach f TestList (prin1 (GetNextValue_Ale TestList f))) (princ)) => 12345678901
(progn (foreach f TestList (prin1 (GetNextValue_pBe TestList f))) (princ)) => 02345678900

(progn (foreach f TestList (prin1 (GetPreviousValue_Ale TestList f))) (princ)) => 00123456780
(progn (foreach f TestList (prin1 (GetPreviousValue_pBe TestList f))) (princ)) => 00123456780

pBe

  • Bull Frog
  • Posts: 401
Re: [challenge]: Get Next/Previous List Item
« Reply #10 on: March 10, 2022, 04:28:38 AM »
(setq TestList '(0 1 2 3 4 5 6 7 8 9 0))

Oh snap!! Doubles! :D