Reputation: 43
This is hard to explain but easy to show. Not sure why I haven't figured it out myself, so I must be missing something in clojure that is obvious.
I need to combine a vector with itself, into a vector, and I need to combine the first element with all the remaining elements, then the 2nd element, with all the remaining elements (3rd and after).
As a short example: [1 2 3 4 5]
I need a function to get: [[1 2] [1 3] [1 4] [1 5] [2 3] [2 4] [2 5] [3 4] [3 5]]
If this looks like getting half the pairs for a large matrix, you are right. I only want to solve half the matrix minus the middle diagonal. This is the only part I need to be sequential(so I only solve half) and the rest I want to use the reducers library to parallelize the heavier math in the background.
Thanks in advance!
Upvotes: 1
Views: 231
Reputation: 3752
(def v [1 2 3 4 5])
(for [i (range (count v))
:let [vv (drop i v)]
r (rest vv)]
[(first vv) r])
=> ([1 2] [1 3] [1 4] [1 5] [2 3] [2 4] [2 5] [3 4] [3 5] [4 5])
Upvotes: 0
Reputation: 15442
I'd just use a for
:
(for [ i (range 1 6) j (range 6) :when (< i j)] [i j])
; => ([1 2] [1 3] [1 4] [1 5] [2 3] [2 4] [2 5] [3 4] [3 5] [4 5])
Upvotes: 3
Reputation: 25269
What you want is built into clojure/math.combinatorics: https://github.com/clojure/math.combinatorics
The basic example you are looking for is on the readme, but for completeness to this answer, I'll repeat it here:
(ns example.core
(:require [clojure.math.combinatorics :as combo]))
(combo/combinations [1 2 3] 2)
;;=> ((1 2) (1 3) (2 3))
Upvotes: 3