Expresión para probar que todos los elementos en secuencia son iguales
-
10-07-2019 - |
Pregunta
¿Hay algún patrón de instancias múltiples en F # en alguna parte?
Considera que estoy trabajando en una lista. Tengo la siguiente coincidencia de patrones
match l with
| [] | [_] -> l //if the list is empty or contains only one item, simply return it
|
//is there a pattern to test if all of the elements are identical?
En otras palabras, pasar [] o [1] simplemente debería devolver la lista y también debería [1; 1; 1; ...] pero no puedo entender cómo un patrón coincide con ese último patrón. es posible? ¿O hay un mejor enfoque que podría usar? No he encontrado nada en ningún lugar sobre un patrón repetitivo .
Solución
No conozco ningún patrón que haga lo que quieres, pero puedes hacer esto:
let allSame L =
match L with
| [] | [_] -> L
| h::t when t |> List.forall ((=) h) -> L
| _ -> failwith "unpossible!" //handle the failing match here
P.S. Estás hablando de una secuencia, pero tu coincidencia indica que estás trabajando con una lista. El código correspondiente para una secuencia sería algo así como
let allSameSeq s =
match Seq.length s with
| 0 | 1 -> s
| _ when Seq.skip 1 s |> Seq.forall ((=) (Seq.head s)) -> s
| _ -> failwith "unpossible!"
Tenga en cuenta que el rendimiento de esta función puede ser peor que el basado en listas.
Otros consejos
Aquí hay una solución que usa patrones activos de casos múltiples.
let (|SingleOrEmpty|AllIdentical|Neither|) (lst:'a list) =
if lst.Length < 2 then
SingleOrEmpty
elif List.forall (fun elem -> elem = lst.[0]) lst then
AllIdentical
else
Neither
let allElementsIdentical lst:'a list =
match lst with
|SingleOrEmpty|AllIdentical -> lst
|Neither -> failwith "Not a suitable list"
Consideraría hacer uno de los siguientes:
yourSequence |> Seq.windowed(2) |> Seq.forall(fun arr -> arr.[0] = arr.[1])
o
let h = Seq.hd yourSequence
yourSequence |> Seq.forall((=) h)
Siempre es bueno usar funciones de biblioteca cuando sea posible;)