2009-07-21 5 views
13

gegeben zwei Sequenzen, wie alle Elemente zu den Sequenzen oder alle Elemente zu einem von ihnen einzigartig?F # Seq diff

Beispiel:

let a = [1..10] 
let b = [3; 5; 7] 

Wie berechnet I 3 5 und 7 (alle Elemente gemeinsamen sowohl der Liste) und 1, 2, 4, 6, 8, 9, 10 (die ganze Elemente nicht gemeinsam)

Dank

+0

Können Sie ein Beispiel geben? – Dario

Antwort

11

Was möchten Sie ist nicht mehr als die einfache Set-Operationen von intersection und difference (oder relative Komplement) zu tun.

F # hat das Set Modul, um uns hier zu helfen. Dies sollte die Arbeit machen:

let a = [1 .. 10] 
let b = [3; 5; 7] 

let intersection = Set.intersect (Set.ofList a) (Set.ofList b) 
let difference = (Set.ofList a) - (Set.ofList b) 

Sie können dann die Ergebnisse in Listen natürlich konvertieren zurück Set.toList verwenden, wenn Sie möchten.

Wie Mehrdad weist darauf hin, kann diese alternativ mit LINQ getan werden (oder sogar die HashSet Klasse in der BCL), aber der Ansatz hier scheint die meisten in dem Geist der F # Sprache zu sein (sicherlich die schönsten syntaktisch und wahrscheinlich auch der effizienteste).

+1

Etwas, worüber man nachdenken sollte, ist, dass bei der Umwandlung einer Liste in eine Menge nur die unterschiedlichen Werte erhalten bleiben (Definition einer Menge). Die Antwort von Mehrdad (unter Verwendung von Linq-Enumerable-Methoden) wird alle Werte behalten, sogar verschiedene. Manchmal ist das kein Problem, aber ich wollte nur darauf hinweisen. – polkduran

+1

(Set.of_list a) - (Set.of_list b) ist nicht kommutativ – Indy9000

4

nicht sehr F # -y Weise, die ich kenne. Sie können immer auf .NET-Bibliotheken zurückgreifen. seq<T> ist nur IEnumerable<T>, nichts Besonderes:

let diff = System.Linq.Enumerable.Except(seq1, seq2); // seq1 - seq2 
let intersect = System.Linq.Enumerable.Intersect(seq1, seq2); 
let symdiff = System.Linq.Enumerable.Union(System.Linq.Enumerable.Except(seq1, seq2), System.Linq.Enumerable.Except(seq2, seq1)); 
+1

Sie funktionieren, aber ich denke, es ist seltsam für eine Sprache, die so stark mit Sequenzen arbeitet, die keine eigenen Methoden (oder Aliase) für solch eine gewöhnliche Aufgabe haben ... – pistacchio

+1

Einverstanden. Es könnte einen mehr Weg geben. Habe gerade die Möglichkeit erwähnt. Warte auf eine bessere Antwort. –

8

etwas kompakter:

let a = set [0;1;2;3] 
let b = set [2;3;4;5] 
let c = a - b 
let d = b - a 
let e = Set.intersect a b 
let f = a + b 
> 
val c : Set<int> = seq [0; 1] 
val d : Set<int> = seq [4; 5] 
val e : Set<int> = seq [2; 3] 
val f : Set<int> = seq [0; 1; 2; 3; ...] 

Danny