好的,這裏有個奇怪的問題。我正在使用FSharp.Data.SqlClient
從我們的數據庫中獲取記錄。它推斷的記錄有幾個選項類型的字段。我需要過濾掉任何選項類型都是None的記錄,並在字段已知的情況下創建新記錄。以下是我正在談論的一個例子。爲了解決這個問題,我創建了一個過濾器函數recordFilter
,它在所有類型的Option<'T>
包含一個值時返回我想要的類型,當它們不包含時則返回None
。F#過濾多種選項的記錄
我的問題是是否有可能創建一個函數,它只是自動檢查記錄中的所有Option<'T>
字段是否有值。我猜這需要某種反射來遍歷記錄的字段。我猜這是不可能的,但我想把它扔到那裏以防萬一我錯了。
如果這種方法是慣用的方法,那麼我會很高興聽到這種說法。我只是想確保我沒有錯過一些更優雅的解決方案。 F#有可能讓我感到驚喜。
我的動機是我正在處理幾十個字段的記錄,其類型爲Option<'T>
。像我在這個例子中那樣寫出大量的match...with
聲明是令人討厭的。當只有幾個領域是好的時候,當它是30+領域時,這是令人討厭的。
type OptionRecord = {
Id: int
Attr1: int option
Attr2: int option
Attr3: int option
Attr4: int option
Attr5: int option
Attr6: int option
}
type FilteredRecord = {
Id: int
Attr1: int
Attr2: int
Attr3: int
Attr4: int
Attr5: int
Attr6: int
}
let optionRecords = [for i in 1..5 ->
{
OptionRecord.Id = i
Attr1 = Some i
Attr2 =
match i % 2 = 0 with
| true -> Some i
| false -> None
Attr3 = Some i
Attr4 = Some i
Attr5 = Some i
Attr6 = Some i
}]
let recordFilter (x:OptionRecord) =
match x.Attr1, x.Attr2, x.Attr3, x.Attr4, x.Attr5, x.Attr6 with
| Some attr1, Some attr2, Some attr3, Some attr4, Some attr5, Some attr6 ->
Some {
FilteredRecord.Id = x.Id
Attr1 = attr1
Attr2 = attr2
Attr3 = attr3
Attr4 = attr4
Attr5 = attr5
Attr6 = attr6
}
| _, _, _, _, _, _ -> None
let filteredRecords =
optionRecords
|> List.choose recordFilter
是否可以使用int選項列表而不是attr1,attr2 ... atr6? – JosephStevens
@JosephStevens這只是一個玩具的例子。實際上它是int,string,decimal等的混合體。我只是用int來表示這個具體的例子 –
Gotcha,然後是的,你將需要使用反射,因爲反射並不是很好,因爲它給你編譯時間錯誤帶來了一個惡意的運行時錯誤習慣。 – JosephStevens