Expression Pour vérifier que tous les éléments de la séquence sont identiques
-
10-07-2019 - |
Question
Existe-t-il un modèle d'instances multiples dans F # quelque part?
Considérez que je travaille sur une liste. J'ai le modèle suivant:
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 d'autres termes, passer [] ou [1] devrait simplement renvoyer la liste, de même que [1; 1; 1; ...], mais je ne vois pas comment faire correspondre ce dernier modèle. Est-ce possible? Ou y a-t-il une meilleure approche que je pourrais utiliser? Je n'ai rien trouvé sur un motif répété .
La solution
Je ne connais aucun modèle qui fasse ce que vous voulez, mais vous pouvez le faire:
let allSame L =
match L with
| [] | [_] -> L
| h::t when t |> List.forall ((=) h) -> L
| _ -> failwith "unpossible!" //handle the failing match here
P.S. Vous parlez d'une séquence, mais votre correspondance indique que vous travaillez avec une liste. Le code correspondant à une séquence serait quelque chose comme
let allSameSeq s =
match Seq.length s with
| 0 | 1 -> s
| _ when Seq.skip 1 s |> Seq.forall ((=) (Seq.head s)) -> s
| _ -> failwith "unpossible!"
Soyez averti que les performances de cette fonction risquent d'être bien pires que celles basées sur des listes.
Autres conseils
Voici une solution utilisant des modèles actifs à plusieurs cas.
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"
J'aimerais envisager l'une des solutions suivantes:
yourSequence |> Seq.windowed(2) |> Seq.forall(fun arr -> arr.[0] = arr.[1])
ou
let h = Seq.hd yourSequence
yourSequence |> Seq.forall((=) h)
Il est toujours bon d'utiliser les fonctions de la bibliothèque lorsque cela est possible;)