2011-02-14 23 views
1
let x = [for p in db.ParamsActXes do 
              if p.NumGroupPar = grp then 
               yield p.Num, p.Name] 

這裏是我的序列,但問題是它返回的元組的列表,我無法訪問單一的元組元素像F#序列 - 如何返回多行

let str = "hello" + x.[1] 

那就是麻煩。

我該如何實現這個工作?

回答

4

要訪問2元組的第二個元素,您可以使用snd或模式匹配。所以,如果tup是2元組,其中tup第二個元素是一個字符串,你可以這樣做:

let str = "hello" + snd tup 

let (a,b) = tup 
let st = "hello" + b 

注意snd只有2元組,不工作具有兩個以上元素的元組。

+0

首先是fst。謝謝你,這是我當前問題的解決方案,但只是有趣的是,如果將有3個或更多的元素?第二個變體對於我當前的任務是不利的。 – Cynede 2011-02-14 08:09:50

+1

@nCdy:如果有三個或更多的元素,你將不得不使用模式匹配或者定義你自己的訪問器(即`let fst_of_3(x,_,_)= x`` let snd_of_3(_,x,_) = x`等) – sepp2k 2011-02-14 08:12:28

1

您可以使用List.nth從元組列表中訪問單個元組。

let first, second = List.nth x 0 

第一個和第二個代表元組的單個元素。

3

爲了給你一個替代解決方案,你可以通過編寫yield p創建包含原始類型的值的過濾序列:

let x = [ for p in db.ParamsActXes do 
      if p.NumGroupPar = grp then 
       yield p ] 

然後就是訪問屬性,你需要:

let str = "hello" + x.[1].Name 

如果您只返回p值的幾個屬性,這可能是一個好主意。產生元組的唯一原因是從代碼的其餘部分隱藏某些東西,或創建與稍後使用的某些函數相匹配的序列。 (另外,我會避免使用x.[i]索引到列表中,因爲這樣做效率很低 - 但也許這僅僅適用於您發佈的示例中的示例。如果需要通過將序列表達式包裝爲[| ... |]來使用索引訪問,請使用數組)

2

只是爲了拋出更多的可能性,如果您運行的是F#2.0的.NET 4.0版本,則可以執行從F#元組到.NET 4.0 System.Tuple的運行時轉換,然後使用ItemX的屬性.NET 4.0元組訪問您需要的元組元素,

let x = (1, 1.2, "hello") 
let y = ((box x) :?> System.Tuple<int, float, string>);; 
y.Item3 //returns "hello" 

但是,我絕不會使用它,而是選擇模式匹配提取。 (另外,我讀過F#編譯器可能並不總是選擇將它的元組表示爲.NET 4.0元組的地方,因此可能會失敗)。

在其他一些答案中閱讀您的意見,我不確定爲什麼模式匹配解決方案不適合您。也許你想在表達式的某個地方訪問元組項目?如果是這樣,以前肯定會工作:

let str = "hello" + ((box x.[1]) :?> System.Tuple<int,string>).Item2 //though might as well use snd and fst for length 2 F# tuples 

,但你可以實現使用匹配的萃取技術太圖案同樣的目的(再次,假設這是即使你後的):

let str = "hello" + (let (_,name) = x.[1] in name)