2009-07-21 16 views
13

dos secuencias, ¿cómo obtener todos los elementos que pertenecen tanto a las secuencias como a todos los elementos exclusivos de una de ellas?F # Seq diff

Ejemplo:

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

¿Cómo calculo 3 5 y 7 (todos los elementos común tanto a la lista) y 1, 2, 4, 6, 8, 9, 10 (todo el elementos en común no)

, gracias

+0

¿Puede dar un ejemplo? – Dario

Respuesta

11

Lo que se quiere hacer es no más que el conjunto de operaciones sencillas de intersection y difference (o complemento relativo).

F # tiene el módulo Set para ayudarnos aquí. Esto debería hacer el trabajo:

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) 

Usted puede entonces, por supuesto, convertir de nuevo los resultados en listas usando Set.toList, si lo desea.

Como señala Mehrdad, esto se puede hacer alternativamente usando LINQ (o incluso la clase HashSet en BCL), pero el enfoque aquí parece ser más acorde con el espíritu del lenguaje F # (sin duda el más simpático sintácticamente, y probablemente el más eficiente también).

+1

Algo en lo que pensar es que al convertir una lista en un conjunto, solo se conservan los valores distintos (definición de un conjunto). La respuesta dada por Mehrdad (usando métodos Linq-Enumerable) mantendrá todos los valores, incluso los distintos. A veces esto no es un problema, pero solo quería señalarlo. – polkduran

+1

(Set.of_list a) - (Set.of_list b) no es conmutativo – Indy9000

4

No muy F # -y manera que conozco. Siempre puede recurrir a las bibliotecas .NET. seq<T> es sólo IEnumerable<T>, nada especial:

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

Funcionan, pero creo que es extraño para un lenguaje que funciona tan fuertemente con secuencias que no tienen sus propios métodos (o alias) para una tarea tan común ... – pistacchio

+1

De acuerdo. Puede haber una forma más F # y. Solo mencioné la posibilidad. Esperando una mejor respuesta. –

8

ligeramente más compacto:

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

Cuestiones relacionadas