Có một hàm như `assoc` trả về tất cả các giá trị khớp không?


7

Các assoc KEY LISTchức năng trả về phần tử đầu tiên của một alistngười có xe bằng KEY.

Có chức năng Emps Lisp tích hợp nào trả về tất cả các phần tử của alistô tô có giá trị bằng KEY, dưới dạng phụ hoặc danh sách các giá trị không? Rốt cuộc, không có yêu cầu rằng có một alistkhóa duy nhất.

Đó là,

(assoc foo '((foo . 5) (bar . 6) (foo . 7))) = '(foo . 5)

Nhưng,

(assoc-all foo '((foo . 5) (bar . 6) (foo . 7))) = '((foo . 5) (foo . 7))

Câu trả lời:


6

Một cái gì đó như thế này?

(require 'cl-lib)

(cl-remove-if-not (apply-partially #'equal 'foo)
                  '((foo . 5) (bar . 6) (foo . 7))
                  :key #'car)

=> ((foo . 5) (foo . 7))
(defun assoc-all (key list &optional testfn)
  "Like `assoc', but returns the list of all matching elements."
  (cl-remove-if-not (apply-partially (or testfn #'equal) key)
                    list :key #'car))

1
Vui lòng đặt tiền tố tên hàm #'thay vì chỉ 'để cho trình biên dịch biết đây là tham chiếu hàm (hoạt động cho cả hai 'equal'car) ..
Damien Cassou

Làm xong; mặc dù theo hiểu biết của tôi, điều này là hoàn toàn dư thừa trong trường hợp này - nó sẽ chỉ ảnh hưởng đến bất cứ điều gì nếu carhoặc equalcó thể không được xác định, không?
phils

Theo định nghĩa của bạn, #'luôn luôn dư thừa vì bạn được cho là chỉ tham chiếu các hàm được xác định :-). Tôi nghĩ rằng đó là một thói quen tốt để luôn trích dẫn tham khảo chức năng của bạn. Và, ai biết được, trình biên dịch byte một ngày nào đó có thể sử dụng thông tin này để tối ưu hóa mã của bạn :-).
Damien Cassou

5

Một giải pháp khác liên quan đến seq-filter:

(seq-filter (lambda (elt) (equal (car elt) 'foo))
            '((foo . 5) (bar . 6) (foo . 7)))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.