2012-06-07 46 views
0

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

(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

澄清抱歉,我的意思是说不应该重复函数的值,但两个函数可能具有相同的值。 – kakarukeys

+0

你的问题目前还不清楚。我不知道为什么你从第一组函数中排除2但不是1。它们都与我能看到的重复(“a”)相关联。 –

+0

排除其中任何一个都可以。 – user1442023

回答

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 ...)),的dup运行功能,将它们全部应用于序列中的相同值。

你也可以测试是否可以

(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)) 

地方,我需要写一个匿名函数明确的,因为你不能嵌套#(...)

+0

澄清:对不起,我的意思是说不应该重复函数的值,但两个函数可能具有相同的值。 2被取出,因为f1在1和2上返回相同的值。4被取出,因为f2在2和4上返回相同的值。啊,这使问题变得更加困难! – kakarukeys