首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >字符串和数组的设置差异

字符串和数组的设置差异
EN

Stack Overflow用户
提问于 2014-06-20 09:12:01
回答 1查看 105关注 0票数 1

set-difference作为筛选函数工作,但只用于列表。数组和字符串是什么?这些类型的数据是否有类似的函数?如果没有这样的功能,实现这些功能的适当方式是什么?

现在,我使用这个宏将任何序列作为列表处理(有时它很有用):

代码语言:javascript
复制
(defmacro treat-as-lists (vars &body body)
  (let ((type (gensym)))
    `(let ((,type (etypecase ,(car vars)
                    (string 'string)
                    (vector 'vector)
                    (list 'list)))
           ,@(mapcar (lambda (x) `(,x (coerce ,x 'list)))
                 vars))
       (coerce (progn ,@body) ,type))))

我的filter

代码语言:javascript
复制
(defun filter (what where &key key (test #'eql))
  (treat-as-lists (what where)
    (set-difference where what :key key :test test)))

示例:

代码语言:javascript
复制
CL-USER> (filter "cat" "can you take this cat away?")
"n you ke his  wy?"
CL-USER> (filter #(0 1) #(1 5 0 1 9 8 3 0))
#(5 9 8 3)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-20 13:23:52

由于编写在所有序列类型上工作的函数通常意味着为列表和向量编写单独的版本,因此在可能的情况下使用在序列上操作的标准函数是值得的。在这种情况下,我们可以使用位置移除-如果。我颠倒了你们论点的顺序,以便使这个序列差更像集差,其中第二个参数被从第一个参数中减去。

代码语言:javascript
复制
(defun sequence-difference (seq1 seq2 &key (start1 0) end1 (start2 0) end2
                                           key (key1 key) (key2 key)
                                           test test-not)
  "Returns a new sequence of the same type of seq1 that contains the
elements of the subsequence of seq1 designated by start1 and end1, and
in the same order, except for those that appear in the subsequence of
seq2 designated by start2 and end2. Test and test-not are used in the
usual way to elements produced by applying key1 (which defaults to
key) to elements from seq1 and by applying key2 (which defaults to
key) to elements from seq2."
  (flet ((in-seq2 (x)
           (not (null (position x seq2
                                :start start2 :end end2
                                :key key2
                                :test test :test-not test-not)))))
    (remove-if #'in-seq2 
               (subseq seq1 start1 end1)
               :key key1)))
代码语言:javascript
复制
(sequence-difference "can you take this cat away?" #(#\c #\a #\t))
;=> "n you ke his  wy?"

(sequence-difference "can you take this cat away?" #(#\c #\a #\t) :start1 3 :start2 1)
" you ke his c wy?"

请注意,该标准还包括发现,它适用于任意序列,但查找返回“序列的一个元素,或为零”。如果零是序列中的一个成员,这将导致歧义。而Position则返回一个索引(它将是一个数字,因此不是null)或null,这样我们就可以可靠地确定一个元素是否是一个按顺序排列的元素。

这里有一个重要的区别,那就是你总是在这里得到一份副本。其原因是主观的:由于序列函数通常采用开始和结束索引参数,因此在这里包含该功能是很好的。但是,如果我们请求(sequence-difference "foobar" "boa" :start1 2),那么我们希望从“foobar”的子序列"obar“中移除b、o和a字符。不过,我们应该返回什么呢?"for“还是"r"?也就是说,我们是否包括seq1中在索引之外的部分?在这个解决方案中,我决定不做,因此我正在做(remove-if … (subseq seq1 …) …),而subseq总是复制。另一方面,如果适当的话,Set-difference可以返回它的list-1或list-2参数.这个实现通常不会返回seq1或seq2,除非在一些病态的情况下(例如,空列表)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24323753

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档