2009-10-29 2 views
1

F #에 여러 인스턴스 패턴이 있습니까?식 시퀀스에서 모든 항목이 동일 함을 테스트하려면

목록 작업 중임을 고려하십시오. [...; 1; 1 1]하지만 난 방법을 알아낼 수 없습니다 나는 다음 [] 통과 또는 [1] 단순히 목록을 반환해야하며, 그렇게해야 즉

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? 

일치하는 패턴을 가지고 그 마지막 패턴과 일치하는 패턴. 이것이 가능한가? 아니면 내가 사용할 수있는 더 나은 접근법이 있습니까? 나는 에 대해 아무 것도 발견하지 못했습니다. 패턴을 반복합니다.

답변

4

은 당신이 원하는 것을 어떤 패턴 모르겠지만, 당신이 할 수있는 :

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

P.S.을 당신은 시퀀스에 대해 이야기하고 있지만, 귀하의 경기는 귀하가리스트로 작업하고 있음을 나타냅니다. 시퀀스에 대한 해당 코드는 무엇인가

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

처럼이 기능의 성능이 아니라 목록 기반보다 악화 될 수 있음을주의 할 것.

+0

@cfern, 네가 맞아. 내가 사용하는 용어에주의해야합니다. 필자는 동의어였던 것처럼 "List"와 "Sequence"를 사용하는 경향이 있으며 F #에서는 동의어가 아닙니다. 나는 명단을 가지고 일하고있다. –

0

나는 다음 중 하나를 수행 생각 하는데요 :


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

또는


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

그것은 가능하면 라이브러리 함수를 사용하는 것이 항상 좋은을) 여기

3

멀티를 사용하여 솔루션 - 케이스 활성 패턴.

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"