获取当前元素和包含Clojure中所有其他内容的列表?

获取当前元素和包含Clojure中所有其他内容的列表?,clojure,list-comprehension,Clojure,List Comprehension,获取包含当前元素对的列表和包含所有其他元素的列表的最快方法是什么?这应该很快,因为列表可能包含一百万个或更多元素 例如,给定列表(1 2 3) 我想获取列表((1(23))(2(13))(3(12))) 谢谢你的帮助 “一百万元素”并不多。如果速度足够快,请尝试: (defn this-and-that [s] (map-indexed (fn [i el] [el (keep-indexed #(if (= %1 i)

获取包含当前元素对的列表和包含所有其他元素的列表的最快方法是什么?这应该很快,因为列表可能包含一百万个或更多元素

例如,给定列表
(1 2 3)

我想获取列表
((1(23))(2(13))(3(12)))

谢谢你的帮助

“一百万元素”并不多。如果速度足够快,请尝试:

(defn this-and-that
  [s]
  (map-indexed (fn [i el]
                 [el (keep-indexed #(if (= %1 i)
                                            nil
                                            %2) s)]) s))
例如:

user> (this-and-that [1 2 3])
([1 (2 3)] [2 (1 3)] [3 (1 2)])

请注意,对于包含
nil

的seq,此代码不能正确工作。这将在不反复遍历整个向量的情况下工作:

(defn this-and-that [xs]
  (map-indexed (fn [i x]
                [x (concat (take i xs) 
                           (drop (inc i) xs))])
              xs))
并且也适用于nils:

user=> (this-and-that [1 2 nil 3])
([1 (2 nil 3)] [2 (1 nil 3)] [nil (1 2 3)] [3 (1 2 nil)])

其他答案给出了很好的实现方法,但是您描述的基本上是一个O(n^2)操作,假设您实际实现了所有的惰性序列等。如果n>=1000000,这可能不是一个好主意

<>你可能想考虑扩大你正在考虑的代码的范围,看看是否可以找到一个更有效的算法。

例如,您可能会发现最好将整个列表转换为向量,并将索引访问方面的算法写入向量。

使用集合如何

user> (let [xs #{1 2 3}]
        (for [x xs] [x (disj xs x)]))
([1 #{2 3}] [2 #{1 3}] [3 #{1 2}])
在一台有一百万件物品的电视机上这样做在时间上也不算太糟糕:

(let [xs (set (range 1000000))]
  (time (count (for [x xs] [x (disj xs x)]))))
"Elapsed time: 841.668 msecs"
1000000