2012-04-11 6 views
1
let private GetDrives = seq{ 
let all=System.IO.DriveInfo.GetDrives() 
for d in all do 
    //if(d.IsReady && d.DriveType=System.IO.DriveType.Fixed) then 
     yield d 
} 

let valid={'A'..'Z'} 
let rec SearchRegistryForInvalidDrive (start:RegistryKey) = seq{ 
    let validDrives=GetDrives |> Seq.map (fun x -> x.Name.Substring(0,1)) 
    let invalidDrives= Seq.toList validDrives |> List.filter(fun x-> not (List.exists2 x b)) //(List.exists is the wrong method I think, but it doesn't compile 

私はF#: Filter items found in one list from another listに従っていますが、私が見ている解決策はどちらもコンパイルされていないため、問題には適用できませんでした。 List.Containsが存在せず(参照がありません)、ListA - ListBもコンパイルされません。無効なドライブ文字のリストを取得する

答えて

7
open System.IO 
let driveLetters = set [ for d in DriveInfo.GetDrives() -> d.Name.[0] ] 
let unused = set ['A'..'Z'] - driveLetters 
+0

したがって、シーケンスを減算することはできますか? C#でセットに最も近いものは何ですか? – Maslow

+3

@Maslow: 'System.Collections.Generic.HashSet <>'であり、LINQには多くのset-like操作があります。 – ildjarn

+1

C#では次のことができます: 'var unused = new HashSet (allLetters); unused.ExceptWith(driveLetters); ' – Daniel

3

あなたの最初のエラーがcharstringの間で混合され、charで始めるのが良いです:

let all = {'A'..'Z'} 
let validDrives = GetDrives |> Seq.map (fun x -> x.Name.[0]) 

今すぐ無効なドライブ文字がvalidDrivesでそれらのallにある文字ではなく、次のとおりです。

let invalidDrives = 
     all |> Seq.filter (fun c -> validDrives |> List.forall ((<>) c)) 

validDrivesは、membをチェックするために何回も横断されているのでこの例では、それをセットに変換する方が良いでしょう:

let all = {'A'..'Z'} 
let validDrives = GetDrives |> Seq.map (fun x -> x.Name.[0]) |> Set.ofSeq 
let invalidDrives = all |> Seq.filter (not << validDrives.Contains) 
関連する問題