2014-10-09 14 views
5

Esiste un metodo o un modo intelligente facile da leggere per creare un elemento combination in Groovy? Sono a conoscenza di Iterable#combinations o GroovyCollections#combinations ma rende Permutazione parziale con ripetizione come ho capito finora. Vedi esempio.Combinazione reale in Groovy

// Groovy combinations result 
def e = ['a', 'b', 'c'] 
def result = [e, e].combinations() 
assert [['a', 'a'], ['b', 'a'], ['c', 'a'], ['a', 'b'], ['b', 'b'], ['c', 'b'], ['a','c'], ['b', 'c'], ['c', 'c']] == result 

// What I'm looking for 
def e = ['a', 'b', 'c'] 
def result = ??? 
assert [['a', 'b'], ['a', 'c'], ['b', 'c']] == result 

Sentitevi liberi di inviare soluzioni alternative. Sto ancora cercando una migliore leggibilità (è usata in script per non sviluppatori) e prestazioni (senza iterazioni inutili).

risposta

9

Non sono così sicuro della leggibilità, ma questo dovrebbe fare il trucco.

def e = ['a', 'b', 'c'] 
def result = [e, e].combinations().findAll { a, b -> 
    a < b 
} 

assert [['a', 'b'], ['a', 'c'], ['b', 'c']] == result 

Si noti che se un elemento si verifica due volte nell'elenco le sue combinazioni si verificheranno anche due volte. Aggiungi un '.unique()' alla fine se sono indesiderati

+0

Grazie. Solo una cosa. Non devi nemmeno testare un! = B cos questa condizione è inclusa in un

+0

Questo è vero, modificato. Grazie. – Kaffeleif

7

Ecco un approccio più generalizzato che consente di specificare il valore "r" per le combinazioni nCr. Lo fa memorizzando le permutazioni in insiemi, con gli insiemi che forniscono l'unicità:

// returns combinations of the input list of the provided size, r 
List combinationsOf(List list, int r) { 
    assert (0..<list.size()).contains(r) // validate input 
    def combs = [] as Set 
    list.eachPermutation { 
     combs << it.subList(0, r).sort { a, b -> a <=> b } 
    } 
    combs as List 
} 

// the test scenario... 
def e = ['a', 'b', 'c'] 
def result = combinationsOf(e, 2) 
assert [['a', 'b'], ['a', 'c'], ['b', 'c']] == result