Jas*_*ban 5 f# query-expressions
leftOuterJoin MSDN上查询表达式的文档通过示例反复暗示,使用时leftOuterJoin .. on .. into ..仍然必须使用它.DefaultIfEmpty()才能达到预期的效果。
我不认为这是必要的,因为我在这两项测试中得到了相同的结果,唯一的区别在于第二个测试没有.DefaultIfEpmty()
type Test = A | B | C
let G = [| A; B; C|]
let H = [| A; C; C|]
printfn "%A" <| query {
for g in G do
leftOuterJoin h in H on (g = h) into I
for i in I.DefaultIfEmpty() do
select (g, i)}
printfn "%A" <| query {
for g in G do
leftOuterJoin h in H on (g = h) into I
for i in I do
select (g, i)}
// seq [(A, A); (B, null); (C, C); (C, C)]
// seq [(A, A); (B, null); (C, C); (C, C)]
Run Code Online (Sandbox Code Playgroud)
1)你能证实这一点吗?
如果这是正确的,我只是在编写这个替代类型增强以尝试更好地处理不匹配的结果之后才意识到这一点,并且我很惊讶仍然null在我的输出中看到 s !
type IEnumerable<'TSource> with
member this.NoneIfEmpty = if (Seq.exists (fun _ -> true) this)
then Seq.map (fun e -> Some e) this
else seq [ None ]
printfn "%A" <| query {
for g in G do
leftOuterJoin h in H on (g = h) into I
for i in I.NoneIfEmpty do
select (g, i)}
// seq [(A, Some A); (B, Some null); (C, Some C); (C, Some C)]
Run Code Online (Sandbox Code Playgroud)
2)有没有办法None代替null/Some null从leftOuterJoin?
3)我真正想做的是找出是否有任何不匹配的g
printfn "%A" <| query {
for g in G do
leftOuterJoin h in H on (g = h) into I
for i in I.NoneIfEmpty do
where (i.IsNone)
exists (true) }
Run Code Online (Sandbox Code Playgroud)
我想出了下一个,但它不是很 F#:
printfn "%A" <| query {
for g in G do
leftOuterJoin h in H on (g = h) into I
for i in I do
where (box i = null)
exists (true)}
Run Code Online (Sandbox Code Playgroud)
简短版本:查询表达式使用空值。这是该语言中的一个难点,但也是可以控制的。
我以前做过这个:
let ToOption (a:'a) =
match obj.ReferenceEquals(a,null) with
| true -> None
| false -> Some(a)
Run Code Online (Sandbox Code Playgroud)
这将让你做:
printfn "%A" <| query {
for g in G do
leftOuterJoin h in H on (g = h) into I
for i in I do
select ( g,(ToOption i))}
Run Code Online (Sandbox Code Playgroud)
它将每个结果包装在一个选项中(因为您不知道是否会有 I。值得注意的是,F#null在运行时使用表示 None 作为优化。所以要检查这是否确实是您想要的,对选项做出决定,例如:
Seq.iter (fun (g,h) ->
printf "%A," g;
match h with
| Some(h) -> printfn "Some (%A)" h
| None -> printfn "None")
<| query {
for g in G do
leftOuterJoin h in H on (g = h) into I
for i in I do
select ((ToOption g),(ToOption i))}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
459 次 |
| 最近记录: |