खोज…


बंधे हुए लूप

हम दोहराव का उपयोग करके किसी संख्या को कई बार repeat

CL-USER> (loop repeat 10 do (format t "Hello!~%"))
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
Hello!
NIL
CL-USER> (loop repeat 10 collect (random 50))
(28 46 44 31 5 33 43 35 37 4)

दृश्यों पर लूपिंग

(loop for i in '(one two three four five six)
      do (print i))
(loop for i in '(one two three four five six) by #'cddr
      do (print i)) ;prints ONE THREE FIVE

(loop for i on '(a b c d e f g)
      do (print (length i))) ;prints 7 6 5 4 3 2 1
(loop for i on '(a b c d e f g) by #'cddr
      do (print (length i))) ;prints 7 5 3 1
(loop for i on '(a b c)
      do (print i)) ;prints (a b c) (b c) (c)

(loop for i across #(1 2 3 4 5 6)
      do (print i)) ; prints 1 2 3 4 5 6
(loop for i across "foo"
      do (print i)) ; prints #\f #\o #\o
(loop for element across "foo"
      for i from 0
      do (format t "~a ~a~%" i element)) ; prints 0 f\n1 o\n1 o

यहां कीवर्ड का सारांश दिया गया है

कीवर्ड अनुक्रम प्रकार चर प्रकार
में सूची सूची का तत्व
पर सूची सूची के कुछ सीडीआर
भर में वेक्टर वेक्टर का तत्व

हैश टेबल्स पर लूपिंग

(defvar *ht* (make-hash-table))
(loop for (sym num) on 
        '(one 1 two 2 three 3 four 4 five 5 six 6 seven 7 eight 8 nine 9 ten 10)
        by #'cddr
      do (setf (gethash sym *ht*) num))

(loop for k being each hash-key of *ht*
      do (print k)) ; iterate over the keys
(loop for k being the hash-keys in *ht* using (hash-value v)
      do (format t "~a=>~a~%" k v))
(loop for v being the hash-value in *ht*
      do (print v))
(loop for v being each hash-values of *ht* using (hash-key k)
      do (format t "~a=>~a~%" k v))

सरल LOOP फार्म

विशेष कीवर्ड के बिना सरल LOOP फॉर्म:

(loop forms...)

लूप से बाहर निकलने के लिए हम उपयोग कर सकते हैं (return <return value>) `

कुछ उदाहरण:

(loop (format t "Hello~%"))  ; prints "Hello" forever
(loop (print (eval (read)))) ; your very own REPL
(loop (let ((r (read)))
        (typecase r
         (number (return (print (* r r))))
         (otherwise (format t "Not a number!~%")))))

पैकेजों पर लूपिंग

(loop for s being the symbols in 'cl
      do (print s))
(loop for s being the present-symbols in :cl
      do (print s))
(loop for s being the external-symbols in (find-package "COMMON LISP")
      do (print s))
(loop for s being each external-symbols of "COMMON LISP"
      do (print s))
(loop for s being each external-symbol in pack ;pack is a variable containing a package
      do (print s))

अंकगणित लूप्स

(loop for i from 0 to 10
      do (print i)) ; prints 0 1 2 3 4 5 6 7 8 9 10
(loop for i from 0 below 10
      do (print i)) ; prints 0 1 2 3 4 5 6 7 8 9 10
(loop for i from 10 above 0
      do (print i)) ; prints 10 9 8 7 6 5 4 3 2 1
(loop for i from 10 to 0
      do (print i)) ; prints nothing
(loop for i from 10 downto 0
      do (print i)) ; prints 10 9 8 7 6 5 4 3 2 1 0
(loop for i downfrom 10 to 0
      do (print i)) ; same as above
(loop for i from 1 to 100 by 10
      do (print i)) ; prints 1 11 21 31 41 51 61 71 81 91
(loop for i from 100 downto 0 by 10
      do (print i)) ; prints 100 90 80 70 60 50 40 30 20 10 0
(loop for i from 1 to 10 by (1+ (random 3))
      do (print i)) ; note that (random 3) is evaluated only once
(let ((step (random 3)))
  (loop for i from 1 to 10 by (+ step 1)
        do (print i))) ; equivalent to the above
(loop for i from 1 to 10
      for j from 11 by 11
      do (format t "~2d ~3d~%" i j)) ;prints 1 11\n2 22\n...10 110

बयानों के लिए विनाशकारी

हम यौगिक वस्तुओं की सूचियों को नष्ट कर सकते हैं

CL-USER> (loop for (a . b) in '((1 . 2) (3 . 4) (5 . 6)) collect a)
(1 3 5)
CL-USER> (loop for (a . b) in '((1 . 2) (3 . 4) (5 . 6)) collect b)
(2 4 6)
CL-USER> (loop for (a b c) in '((1 2 3) (4 5 6) (7 8 9) (10 11 12)) collect b)
(2 5 8 11)

हम एक सूची को भी नष्ट कर सकते हैं

CL-USER> (loop for (a . b) on '(1 2 3 4 5 6) collect a)
(1 2 3 4 5 6)
CL-USER> (loop for (a . b) on '(1 2 3 4 5 6) collect b)
((2 3 4 5 6) (3 4 5 6) (4 5 6) (5 6) (6) NIL)

यह उपयोगी है जब हम केवल कुछ तत्वों के माध्यम से पुनरावृति करना चाहते हैं

CL-USER> (loop for (a . b) on '(1 2 3 4 5 6) by #'cddr collect a)
(1 3 5)
CL-USER> (loop for (a . b) on '(1 2 3 4 5 6) by #'cdddr collect a)
(1 4)

किसी शब्द को अनदेखा करने के लिए NIL का उपयोग करना:

(loop for (a nil . b) in '((1 2 . 3) (4 5 . 6) (7 8 . 9))
      collect (list a b)) ;=> ((1 3) (4 6) (7 9))
(loop for (a b) in '((1 2) (3 4) (5 6)) ;(a b) == (a b . nil)
      collect (+ a b)) ;=> (3 7 11)

; iterating over a window in a list
(loop for (pre x post) on '(1 2 3 4 5 3 2 1 2 3 4)
      for nth from 1
      while (and x post) ; checks that we have three elements of the list
      if (and (<= post x) (<= pre x)) collect (list :max x nth)
      if (and (>= post x) (>= pre x)) collect (list :min x nth))
; The above collects local minima/maxima

अभिव्यक्ति के रूप में LOOP

आज उपयोग की जाने वाली लगभग हर अन्य प्रोग्रामिंग भाषा में छोरों के विपरीत, कॉमन लिस्प में LOOP को एक अभिव्यक्ति के रूप में इस्तेमाल किया जा सकता है:

(let ((doubled (loop for x from 1 to 10
                     collect (* 2 x))))
    doubled) ;; ==> (2 4 6 8 10 12 14 16 18 20)

(loop for x from 1 to 10 sum x)

MAXIMIZE कारण बनता है कि LOOP का मूल्यांकन किया गया सबसे बड़ा मान लौटाया जाए। MINIMIZE के विपरीत है MAXIMIZE

(loop repeat 100
      for x = (random 1000)
      maximize x)

COUNT आपको बताता है कि लूप के दौरान गैर- NIL को कितनी बार अभिव्यक्ति का मूल्यांकन किया गया है:

(loop repeat 100
      for x = (random 1000)
      count (evenp x))

LOOP में some , every और notany फ़ंक्शन के notany हैं:

(loop for ch across "foobar"
     thereis (eq ch #\a))

(loop for x in '(a b c d e f 1)
    always (symbolp x))

(loop for x in '(1 3 5 7)
    never (evenp x))

... सिवाय इसके कि वे सीक्वेंस पर चलने तक सीमित नहीं हैं:

(loop for value = (read *standard-input* nil :eof)
   until (eq value :eof)
   never (stringp value))

LOOP मूल्य-सृजन करने वाली क्रियाओं को भी एक प्रत्यय के साथ लिखा जा सकता है:

(loop repeat 100
      for x = (random 1000)
      minimizing x)

इन क्रियाओं द्वारा उत्पन्न मूल्य को चर में उत्पन्न करना भी संभव है (जो कि LOOP मैक्रो द्वारा निहित रूप से बनाए गए हैं), इसलिए आप एक समय में एक से अधिक मूल्य उत्पन्न कर सकते हैं:

 (loop repeat 100
     for x = (random 1000)
     maximizing x into biggest
     minimizing x into smallest
     summing x into total
     collecting x into xs
     finally (return (values biggest smallest total xs)))

आपके पास एक से अधिक collect , count , आदि खंड हो सकते हैं जो समान आउटपुट मान में एकत्रित होते हैं। उन्हें क्रम से निष्पादित किया जाएगा।

निम्नलिखित एक संपत्ति सूची में एक एसोसिएशन सूची (जिसका उपयोग आप assoc साथ कर सकते हैं) में कनवर्ट करता है (जिसे आप getf साथ उपयोग कर सकते हैं):

(loop for (key . value) in assoc-list
      collect key
      collect value)

हालांकि यह बेहतर शैली है:

(loop for (key . value) in assoc-list
      append (list key value))

सशर्त रूप से LOOP क्लॉज़ निष्पादित किया जा रहा है

LOOP का अपना IF कथन है जो यह नियंत्रित कर सकता है कि खण्डों को कैसे निष्पादित किया जाता है:

(loop repeat 1000
      for x = (random 100)
      if (evenp x)
        collect x into evens
      else
        collect x into odds
      finally (return (values evens odds)))

एक IF बॉडी में कई क्लॉज़ को मिलाने के लिए विशेष सिंटैक्स की आवश्यकता होती है:

 (loop repeat 1000
       for x = (random 100)
       if (evenp x)
          collect x into evens
          and do (format t "~a is even!~%" x)
       else
          collect x into odds
          and count t into n-odds
       finally (return (values evens odds n-odds)))

समानांतर Iteration

एकाधिक FOR खंड एक में अनुमति दी जाती LOOP । जब इन खंडों में से पहला खत्म हो जाता है तो लूप समाप्त हो जाता है:

(loop for a in '(1 2 3 4 5)
      for b in '(a b c)
      collect (list a b))
;; Evaluates to: ((1 a) (2 b) (3 c))

अन्य खंड जो निर्धारित करते हैं कि क्या लूप जारी रहना चाहिए संयुक्त हो सकता है:

(loop for a in '(1 2 3 4 5 6 7)
      while (< a 4)
      collect a)
;; Evaluates to: (1 2 3)

(loop for a in '(1 2 3 4 5 6 7)
      while (< a 4)
      repeat 1
      collect a)
;; Evaluates to: (1)

निर्धारित करें कि कौन सी सूची लंबी है, उत्तर ज्ञात होते ही पुनरावृति काट देना:

(defun longerp (list-1 list-2)
    (loop for cdr1 on list-1
          for cdr2 on list-2
          if (null cdr1) return nil
          else if (null cdr2) return t
          finally (return nil)))

किसी सूची के तत्वों की संख्या:

(loop for item in '(a b c d e f g)
      for x from 1
      collect (cons x item))
;; Returns ((1 . a) (2 . b) (3 . c) (4 . d) (5 . e) (6 . f) (7 . g))

सुनिश्चित करें कि किसी सूची में सभी संख्याएँ समान हैं, लेकिन केवल पहले 100 आइटमों के लिए:

(assert
   (loop for number in list
         repeat 100
         always (evenp number)))

नेस्ट इटरेशन

विशेष LOOP NAMED foo सिंटैक्स आपको एक लूप बनाने की अनुमति देता है जिससे आप जल्दी से बाहर निकल सकते हैं। निकास return-from का उपयोग करके किया जाता return-from , और नेस्टेड छोरों के भीतर से उपयोग किया जा सकता है।

निम्नलिखित एक नेस्टेड लूप का उपयोग करता है जो किसी जटिल संख्या को 2D सरणी में देखने के लिए करता है:

(loop named top
      for x from 0 below (array-dimension *array* 1)
      do (loop for y from 0 below (array-dimension *array* 0))
               for n = (aref *array* y x)
             when (complexp n)
               do (return-from top (values n x y))))

रिटन क्लॉज बनाम रिटन फॉर्म।

एक LOOP भीतर, आप किसी भी अभिव्यक्ति में कॉमन लिस्प (return) फॉर्म का उपयोग कर सकते हैं, जिसके कारण LOOP फॉर्म तुरंत return दिए गए मूल्य का मूल्यांकन करेगा।

LOOP में एक return क्लॉज भी है जो लगभग समान रूप से काम करता है, एकमात्र अंतर यह है कि आप इसे कोष्ठक के साथ नहीं घेरते हैं। खण्ड का उपयोग LOOP के डीएसएल के भीतर किया जाता है, जबकि प्रपत्र का उपयोग अभिव्यक्तियों के भीतर किया जाता है।

(loop for x in list
      do (if (listp x) ;; Non-barewords after DO are expressions
             (return :x-has-a-list)))

;; Here, both the IF and the RETURN are clauses
(loop for x in list
     if (listp x) return :x-has-a-list)

;; Evaluate the RETURN expression and assign it to X...
;; except RETURN jumps out of the loop before the assignment
;; happens.
(loop for x = (return :nothing-else-happens)
      do (print :this-doesnt-print))

finally बात एक अभिव्यक्ति होनी चाहिए, इसलिए (return) फॉर्म का इस्तेमाल किया जाना चाहिए न कि return क्लॉज:

 (loop for n from 1 to 100
       when (evenp n) collect n into evens
       else collect n into odds
      finally return (values evens odds)) ;; ERROR!

 (loop for n from 1 to 100
       when (evenp n) collect n into evens
       else collect n into odds
      finally (return (values evens odds))) ;; Correct usage.

किसी सूची की विंडो पर लूपिंग

आकार 3 की विंडो के लिए कुछ उदाहरण:

;; Naïve attempt:
(loop for (first second third) on '(1 2 3 4 5)
      do (print (* first second third)))
;; prints 6 24 60 then Errors on (* 4 5 NIL)

;; We will try again and put our attempt into a function
(defun loop-3-window1 (function list)
  (loop for (first second third) on list
        while (and second third)
        do (funcall function first second third)))
(loop-3-window1 (lambda (a b c) (print (* a b c))) '(1 2 3 4 5))
;; prints 6 24 60 and returns NIL
(loop-3-window1 (lambda (a b c) (print (list a b c))) '(a b c d nil nil e f))
;; prints (a b c) (b c d) then returns NIL

;; A second attempt
(defun loop-3-window2 (function list)
  (loop for x on list
        while (nthcdr 2 x) ;checks if there are at least 3 elements
        for (first second third) = x
        do (funcall function first second third)))
(loop-3-window2 (lambda (a b c) (print (list a b c))) '(a b c d nil nil e f))
;; prints (a b c) (b c d) (c d nil) (c nil nil) (nil nil e) (nil e f)

;; A (possibly) more efficient function:
(defun loop-3-window2 (function list)
  (let ((f0 (pop list))
        (s0 (pop list)))
    (loop for first = f0 then second
          and second = s0 then third
          and third in list
          do (funcall function first second third))))

;; A more general function:
(defun loop-n-window (n function list)
  (loop for x on list
        while (nthcdr (1- n) x)
        do (apply function (subseq x 0 n))))
;; With potentially efficient implementation:
(define-compiler-macro loop-n-window (n function list &whole w)
  (if (typep n '(integer 1 #.call-arguments-limit))
     (let ((vars (loop repeat n collect (gensym)))
           (vars0 (loop repeat (1- n) collect (gensym)))
           (lst (gensym)))
       `(let ((,lst ,list))
          (let ,(loop for v in vars0 collect `(,v (pop ,lst)))
            (loop for
                  ,@(loop for v0 in vars0 for (v vn) on vars
                     collect v collect '= collect v0 collect 'then collect vn
                     collect 'and)
                  ,(car (last vars)) in ,lst
                  do ,(if (and (consp function) (eq 'function (car function))
     w


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow