代码之家  ›  专栏  ›  技术社区  ›  Onorio Catenacci

表达式以测试序列中的所有项是否相同

  •  3
  • Onorio Catenacci  · 技术社区  · 16 年前

    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;...] 但我不知道如何匹配最后的模式。这可能吗?还是有更好的方法可以使用?我在任何地方都没有找到关于a的任何东西 重复 图案

    3 回复  |  直到 16 年前
        1
  •  8
  •   cfern    16 年前

    我不知道有哪种模式符合您的要求,但您可以这样做:

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

    另外,你说的是一个序列,但你的匹配表明你正在处理一个列表。序列的对应代码如下所示

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

    请注意,此函数的性能可能比基于列表的函数差。

        2
  •  4
  •   m-sharp    16 年前

    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"
    
        3
  •  2
  •   em70    16 年前

    我会考虑做以下的一件事:

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

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

    尽可能使用库函数总是好的;)