2013-04-11 5 views
2

내가 찾고있는 것을 찾았을 때 maphash에서 일찍 종료해야합니다.Emacs Lisp에서 maphash를 깨는 방법?

(defun find-in-hash (str hash) 
    (let ((match nil)) 
    (maphash (lambda (key value) 
     (if (string-prefix-p str key) 
     (setq match key))) hash) 
    match)) 

어떻게하면 Emacs Lisp에서이 작업을 수행 할 수 있습니까?

+1

인가 (나는 아직 initially 유사 아무것도하지 않는) 이맥스 리스프 : 방법은 루프 브레이크/종료합니다 (HTTP를 : // ergoemacs.org/emacs/elisp_break_loop.html) 또는 [maphash를 방해하는 방법] (http://osdir.com/ml/lisp.allegro/2006-04/msg00018.html) 도움? –

+0

이것은 올바른 형식이 아닙니다 (괄호 안의 부주의, 오도 된 들여 쓰기). – Svante

+1

대신 trie 사용에 대해 생각해 보셨습니까? – Svante

답변

5

으로는 how to interrupt maphash 당신이 블록 안에 maphash을 배치 할 수 있습니다 및 return-from를 통해 블록을 종료, 즉이 (require 'cl)를 통해 요구 될 수 cl을 요구하는 형태를

(block stop-mapping 
    (maphash 
    ;; Function to call for all entries in ht. 
    ;; A condition for when to stop mapping. 
    (return-from stop-mapping) 
    ht)) 

주 사용 설명했다. As mentioned in a comment 같은 결과는

(catch 'stop-mapping 
    (maphash 
    ;; Function to call for all entries in ht. 
    ;; A condition for when to stop mapping. 
    (throw 'stop-mapping retval) 
    ht)) 
+0

위의 코드는'cl'을 사용해야합니다.'block stop-mapping'을'catch 'stop-mapping'으로 대체하고'return-from top-mapping'을'throw 'stop-mapping'으로 바꾸면 "plain Elisp"에서 같은 결과를 얻을 수 있습니다. – Stefan

+0

@Stefan 그러나 Emacs가 설치되어있을 때'block'과'return-from' 둘 다 문서화되어 있기 때문에 가능합니다. –

+3

'(require'cl ') 이후에만 사용할 수 있습니다. 대부분 당신이 사용하고있는 다른 패키지가'require'를 한 것입니다. 그래서 당신이 그것을 보았습니다. 어쨌든'block'과'return-from'은'cl' 패키지에 구현 된 매크로이고'catch'와'throw'를 사용하는 코드로 확장됩니다. – Stefan

3

를 통해 순수 elisp에 달성 될 수있다 여기에 자기 홍보 :) 내가 일한지

(비록 꽤 많은 최근) 매크로의 집합에서의 비트 Emacs Lisp에서 사용 가능한 다양한 콜렉션에서 모든 종류의 반복 작업을보다 균일하게, 잘하면, 쉽게 할 수 있습니다. 여기있다 : https://code.google.com/p/i-iterate/ 그것은 100 % 완성되지 않고 테스트되었지만 대부분은 그렇다.

이미 말했듯이 maphash에서 깨는 유일한 방법은 오류를 던집니다. 그러나 이것은 Emacs Lisp이 디자인되었을 때 얻은 것입니다. 많은 오래된 언어에는 언어 수준의 반복 추상화가없는 반면 특정 컬렉션을 반복하거나 숫자 반복을 수행하는 특수 기본 요소가 있습니다. loop 매크로 cl Emacs Lisp의 패키지는 상황을 해결하는 좋은 방법이지만, 본질적으로 Common Lisp에서 동일한 매크로를 미러링해야하며 매크로는 확장 가능하지 않습니다 (자체 드라이버를 추가 할 수는 없습니다). , 심지어 일부 구현을 허용하는 경우).

제가 작업 한 라이브러리는 또 다른 Common Lisp 라이브러리 인 Spirit :을 따르고 많은 아이디어를 빌립니다.

그냥 loop 매크로가 무엇을 할 수 있는지 설명하기 :

(loop with hash = (make-hash-table) 
     initially 
     (setf (gethash 'a hash) 'b 
      (gethash 'b hash) 'b 
      (gethash 'c hash) 'c)  ; initialize variables 
             ; before any iteration happens 
     for x being the hash-key in hash 
     using (hash-value y)    ; define variables used in iteration 
     collect (list x y) into z  ; some predefined functionality 
     until (eq x y)     ; termination condition 
     finally (return (cons 'd z))) ; returning from iteration 
;; (d (a b) (b b)) 

를 해시 테이블, 배열 또는 목록에 대해 유사하게 작업 그것의 혜택과 함께.

사용하여 비슷한 코드 ++ 매크로 :

(++ (with ((hash (let ((h (make-hash-table))) 
        (setf (gethash 'a h) 'b 
         (gethash 'b h) 'b 
         (gethash 'c h) 'c) h)))) 
    (for (x . y) pairs hash) 
    (collect (list x y) into z) 
    (when (eq x y) (return (cons 'd z)))) 
;; (d (b b) (a b)) 

관련 문제