シーケンス内のすべてのアイテムが同じであることをテストする式

StackOverflow https://stackoverflow.com/questions/1642795

  •  10-07-2019
  •  | 
  •  

質問

F#にはどこかに複数インスタンスパターンがありますか?

リストに取り組んでいると考えてください。次のパターンマッチングがあります

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?

つまり、[]または[1]を渡すとリストが返されるだけなので、[1; 1; 1; ...]を返す必要がありますが、その最後のパターンとパターンマッチングする方法がわかりません。これは可能ですか?または、私が使用するより良いアプローチがありますか? 繰り返しパターンについては何も見つかりませんでした。

役に立ちましたか?

解決

私はあなたが望むことをするパターンを知りませんが、あなたはこれを行うことができます:

let allSame L =
    match L with
    | [] | [_] -> L
    | h::t when t |> List.forall ((=) h) -> L
    | _ -> failwith "unpossible!" //handle the failing match here

PSあなたはシーケンスについて話しているが、あなたのマッチはあなたがリストで作業していることを示している。シーケンスに対応するコードは次のようになります

let allSameSeq s = 
    match Seq.length s with
    | 0 | 1 -> s
    | _ when Seq.skip 1 s |> Seq.forall ((=) (Seq.head s)) -> s
    | _ -> failwith "unpossible!"

この関数のパフォーマンスはリストベースのものよりもかなり悪いかもしれないことに注意してください。

他のヒント

これは、複数ケースのアクティブパターンを使用したソリューションです。

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"

次のいずれかを行うことを検討します。


yourSequence |> Seq.windowed(2) |> Seq.forall(fun arr -> arr.[0] = arr.[1])

または


let h = Seq.hd yourSequence
yourSequence |> Seq.forall((=) h)

可能な場合はライブラリ関数を使用するのが常に良い;)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top