0

我需要定义一个函数,它接受一个序列和一些作用于序列内元素的函数。它从旧序列返回一个序列,其中删除了具有重复函数值的元素。

(defn dedup [seq & functions] ...)

例如,如果

(f1 1) = 'a'
(f1 2) = 'a'
(f1 3) = 'c'
(f1 4) = 'd'

(f2 1) = 'za'
(f2 2) = 'zb'
(f2 3) = 'zc'
(f2 4) = 'zb'

然后

(dedup [1 2 3 4] f1 f2) 

返回 (1 3) 的序列

我该怎么做?

编辑:编辑测试值以免造成误解

编辑:下面是只有 1 个功能的情况下的(不是那么功能)实现

(defn dedup [seq f]
  (loop [values #{} seq1 seq seq2 '()]
    (let [s (first seq1)]
      (if (nil? s)
        (reverse seq2)
        (let [v (f s)]
          (if (contains? values v)
            (recur values (rest seq1) seq2)
            (recur (conj values v) (rest seq1) (conj seq2 s))))))))
4

1 回答 1

3

您的示例似乎与文本相矛盾-它返回两个函数一致的值。

(defn dedup [seq & fns]
  (for [s seq :when (apply = (map #(% s) fns))] s))

(dedup [1 2 3 4] 
  #(case % 1 "a" 2 "a" 3 "c" 4 "d") 
  #(case % 1 "a" 2 "b" 3 "c" 4 "b"))
(1 3)

也许这有点太紧凑了? #(... % ...) 相当于(fn [x] (... x ...))并且mapindup在函数上运行,将它们全部应用于序列中的相同值。

你也可以用

(dedup [1 2 3 4] {1 "a" 2 "a" 3 "c" 4 "d"} {1 "a" 2 "b" 3 "c" 4 "b"})
(1 3)

ps我想也许混淆是超过英语的意思。“重复”意味着一个值重复。所以“a”“a”是“a”的副本。一世怀疑您的意思是“多个”-您想删除获得多个(不同)值的条目。

pps 你也可以使用filter

(defn dedup [seq & fns] 
  (filter #(apply = (map (fn [f] (f %)) fns)) seq))

我需要显式编写一个匿名函数,因为你不能嵌套#(...)

于 2012-06-07T11:47:47.927 回答