2016-10-05 9 views
1

私はLISPでループを使う方法を理解しようとしていますが、実際には正しく動作していないようです。私は次のコードを使ってみました:LISPでループを使う方法

(loop for i from 0 to (list-length y) 
      (when (eq (values-list (nth i (car y))) 0) 
      (return-from checkZero t))) 

私の値が0であるかどうかチェックすることで、リストをループする必要があります。等しい場合はループから戻り、ループを終了する必要があります。そうでない場合は、リストの長さに達するまで実行されます。私はこの誤ったことを考えていますか?もしそうなら、このループを修正するにはどうしたらいいですか?

(私はまだ間違って使用されるループによって生成されたエラーに対処していると私はオンラインループを使用するために多くの良いリソースを見つけることができないので、私はまだ私の実際のコードが動作するかどうかわからないか)

+1

は '(とき(EQの周りに括弧を削除します... ) '(return-from ...)'( 'return-from ...)'の前に 'do'を置くようにします。 – Renzo

+4

[Practical Common Lisp](http://www.gigamonkeys.com/book/)には、[LOOP for Black Belts]というループの章があります(http://www.gigamonkeys.com/book/loop-for-black -belts.html)。 [Lispの土地](http://landoflisp.com/)の本では、[実用的なチートシート](http://blog.idorobots.org/media/lolreview/3.png) – Sylwester

答えて

4

ループの主な問題はWHEN-expressionです。あなたはそれを書くことができる2つの方法があります。

(loop for... 
     do (when (eq ...) 
      (return-from ...))) 
:ループ DO -clause内部の定期的な WHEN -macroを使用

(loop for... 
     when (eq ...) do (return-from ...)) 
    1. はループWHEN condition DO forms -clauseを使用します

    コード内で修正する必要があるものがいくつかあります。

    1. Lispで物事を命名、言葉ではなく、キャメルケース(check-zeroではなくcheckZero)との間にダッシュを使用しています。
    2. 一般的な数値比較の場合は=、数字がゼロであることを確認する場合はZEROPを使用してください。 EQは、2つのオブジェクトが同じオブジェクトであるかどうかをチェックするために使用されます。
    3. あなたは私はあなたが(VALUES-LIST (NTH ... (CAR ...)))で達成しようとしているものはかなりわからないんだけど、それを動作させるつもりはないRETURN
    4. を使用してループから戻ることができます。フラットな値のリスト(たとえば(1 2 3 4 5 6))をループする場合は、ループFOR item IN listを使用する必要があります。

    だから今、あなたのようなものが必要です:

    (defun check-zero (list) 
        (loop for item in list 
         when (zerop item) do (return t))) 
    

    LOOPはまた、あなたが使用することができTHEREIS condition -clauseがあります

    (defun check-zero (list) 
        (loop for item in list 
         thereis (zerop item))) 
    

    このリターンをするとすぐに、そのアイテムを見つけるとZEROPを満たす。しかし、それを達成するためのより簡単な方法があります。これは一般的なブール値を返します

    (defun check-zero (list) 
        (member 0 list :test #'=)) 
    
    CL-USER> (check-zero '(1 3 4 3 5 7)) 
    NIL 
    CL-USER> (check-zero '(1 3 4 3 0 5 7)) 
    (0 5 7) 
    

    :リストにはゼロが含まれているかどうかをチェックするためにMEMBERを使用することができます。つまり、NILでない値は、Common Lispでは真と見なされます。オブジェクトがゼロであるかどうかを確認するために述語関数(ZEROP)があるので

    、あなたもこのためSOMEまたはMEMBER-IFを使用することができます。

    (some #'zerop '(1 3 4 6 2 0 45 6 7)) ;=> T 
    (member-if #'zerop '(1 3 4 6 2 0 45 6 7)) ;=> (0 45 6 7) 
    
  • +0

    軽い警告、チェックするリストに正しく非数字が含まれている場合は、 'equalp'(0と0.0を等しく比較したい場合)または' eql'(数値と数値の両方を同じにしたい場合)を使用します.zerop引数が非数で '='がそうであるとすれば、エラーを通知するはずです。 – Vatine

    関連する問題