我需要定义一个函数,它接受一个序列和一些作用于序列内元素的函数。它返回旧序列中的序列,其中删除了具有重复函数值的元素。
(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))))))))
答案 0 :(得分: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 ...))
,而map
中的dup
会在函数上运行,并将它们全部应用于序列中的相同值。
你也可以用
进行测试(dedup [1 2 3 4] {1 "a" 2 "a" 3 "c" 4 "d"} {1 "a" 2 "b" 3 "c" 4 "b"})
(1 3)
我认为也许混淆超过了英语的含义。 “重复”表示重复一个值。所以“a”“a”是“a”的副本。我怀疑你的意思是“多重” - 你想删除你获得多个(不同)值的条目。
pps你也可以使用filter
:
(defn dedup [seq & fns]
(filter #(apply = (map (fn [f] (f %)) fns)) seq))
我需要明确写一个匿名函数,因为你无法嵌套#(...)
。