クエリ式の概要
クエリ式(= query式)はF#でLINQをサポートするために存在しているコンピュテーション式です。
LINQというのは、SQLのような文法でデータの集合を操作するための機能のことです。C#では非常によく使われる機能の一つです。それをF#でも利用できるようにしたのが、このクエリ式というわけです。
クエリ式は、主にデータベースの操作によく使われますが、list型やarray型に使用しても問題ありません。ただし、list型などは、それぞれに特化したListモジュールやArrayモジュールを利用するのが一般的ですので、状況に合わせて使い分けできるとよいでしょう。
// [ 構文 ]
query { expression }
構文の「expression」には、クエリ式内で有効なクエリ演算子などを利用した式が記述されます。
以下は、select演算子を用いた、クエリ式の簡単な例です。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ========================================================= | |
// クエリ式のサンプル | |
// ========================================================= | |
// Nugetから [FSharp.Data.TypeProviders] を導入します. | |
// また, 参照設定から [System.Data.Services.Client] も追加しておきます. | |
open FSharp.Data.TypeProviders | |
type Northwind = ODataService<"http://services.odata.org/Northwind/Northwind.svc"> | |
let db = Northwind.GetDataContext() | |
// クエリ式 | |
let query1 = | |
query { | |
for customer in db.Customers do | |
select customer | |
} | |
// クエリ式の結果を出力 | |
query1 | |
|> Seq.iter (fun customer -> printfn "Company: %s Contact: %s" customer.CompanyName customer.ContactName) | |
// | |
// output: | |
// Company: Alfreds Futterkiste Contact: Maria Anders | |
// Company: Ana Trujillo Emparedados y helados Contact: Ana Trujillo | |
// Company: Antonio Moreno Taqueria Contact: Antonio Moreno | |
// Company: Around the Horn Contact: Thomas Hardy | |
// Company: Berglunds snabbkop Contact: Christina Berglund | |
// Company: Blauer See Delikatessen Contact: Hanna Moos | |
// Company: Blondesddsl pere et fils Contact: Frederique Citeaux | |
// Company: Bolido Comidas preparadas Contact: Martin Sommer | |
// Company: Bon app' Contact: Laurence Lebihan | |
// Company: Bottom-Dollar Markets Contact: Elizabeth Lincoln | |
// Company: B's Beverages Contact: Victoria Ashworth | |
// Company: Cactus Comidas para llevar Contact: Patricio Simpson | |
// Company: Centro comercial Moctezuma Contact: Francisco Chang | |
// Company: Chop-suey Chinese Contact: Yang Wang | |
// Company: Comercio Mineiro Contact: Pedro Afonso | |
// Company: Consolidated Holdings Contact: Elizabeth Brown | |
// Company: Drachenblut Delikatessen Contact: Sven Ottlieb | |
// Company: Du monde entier Contact: Janine Labrune | |
// Company: Eastern Connection Contact: Ann Devon | |
// Company: Ernst Handel Contact: Roland Mendel | |
// | |
クエリ演算子の概要
クエリ演算子を利用すると、データの集合から「ある条件」に合致するデータのみを取得したり、取得したデータ群をソートしたりするなどの処理を、SQLのように簡単に記述することが可能となります。ただし、対象のデータ集合がクエリ演算子をサポートしている必要があります。サポートされていないクエリ演算子を使用すると、System.NotSupportedExceptionがthrowされます。
クエリ式にはSQL式に変換できる式のみ使用することが可能です。たとえば、whereクエリ演算子を使用する場合には、式の中で関数呼び出しをすることはできません。このように、各クエリ演算子によって許容されているコードが違いますので、注意しましょう。
以下にクエリ演算子の一部を紹介いたします。ここで紹介するものがすべてではありませんので、その点ご留意ください。(今後すべての演算子を紹介できるよう、時々アップデートしていきます)
contains
containsクエリ演算子は、選択した要素に指定の要素が含まれるかどうかを確認します。指定した要素が含まれる場合に、trueを返します。
// -------------------------------
// contains クエリ演算子のサンプル
// 0 ~ 9のlist
let ls = [0..9]
query {
for i in ls do
contains 5
}
|> printfn "contains 5= %b"
// output:
// contains 5= true
query {
for i in ls do
contains 10
}
|> printfn "contains 10= %b"
// output:
// contains 10= false
distinct
distinctクエリ演算子は、選択した要素から重複なしのシーケンスを作成します。
// -------------------------------
// distinct クエリ演算子のサンプル
// 重複のあるリスト
let ls = [ 0; 0; 1; 2; 3; 3; 4; 5; 5; 5; 5; ]
query {
for i in ls do
distinct // 重複なしのSeqを作成します.
}
|> Seq.toArray
|> printfn "distinct= %A"
// output:
// distinct= [|0; 1; 2; 3; 4; 5|]
query {
for i in ls do
where (5 <= i) // 5以上の値を抽出します.
distinct // 重複なしのSeqを作成します.
}
|> Seq.toArray
|> printfn "distinct= %A"
// output:
// distinct= [|5|]
exists
existsクエリ演算子は、選択した要素に特定の要素が存在しているかチェックします。条件に合致する特定の要素が存在している場合に、true を返します。
// -------------------------------
// exists クエリ演算子のサンプル
let ls = [ 0..9 ]
query {
for i in ls do
exists (i < 0) // ls の中に 0未満の数値 が存在しているかチェックします.
}
|> printfn "exists (i < 0)= %b"
// output:
// exists (i < 0)= false
query {
for i in ls do
where (5 <= i) // 5以上の値を抽出します.
exists (i = 7) // whereで抽出した数値の中に 7 が存在しているかチェックします.
}
|> printfn "exists (i = 7)= %b"
// output:
// exists (i = 7)= true
find
findクエリ演算子は、指定された条件を満たす値を検索し、 条件を満たす最初の要素を取得してきます.
// -------------------------------
// find クエリ演算子のサンプル
let ls = [ 0..9 ]
query {
for i in ls do
find (2 <= i) // lsの中から 2以上の値 を検索し, 条件を満たす先頭の要素を取得します.
}
|> printfn "find (2 <= i)= %d"
// output:
// find (2 <= i)= 2
query {
for i in ls do
where (5 <= i) // 5以上の値を抽出します.
find (i = 7) // whereで抽出した数値の中から 7 を検索します.
}
|> printfn "find (i = 7)= %d"
// output:
// find (i = 7)= 7
// 条件に合致する値がない場合, System.InvalidOperationException が throw されます.
query {
for i in ls do
find (i < 0)
}
|> printfn "find (i < 0)= %d"
// output:
// ハンドルされていない例外: System.InvalidOperationException:
// シーケンスに、一致する要素は含まれてません
all
allクエリ演算子は、これまでに抽出した値のすべての要素が条件を満たすかどうかをチェックします。 すべての要素が条件を満たす場合、true を返します。
// -------------------------------
// all クエリ演算子のサンプル
let ls = [ 0..9 ]
query {
for i in ls do
all (2 <= i) // すべての要素が 2以上 かチェックします.
}
|> printfn "all (2 <= i)= %b"
// output:
// all (2 <= i)= false
query {
for i in ls do
where (5 <= i) // 5以上の値を抽出します.
all (5 <= i && i < 10) // 現在選択中の要素が 5以上, 10未満 かチェックします.
}
|> printfn "all (5 <= i && i < 10)= %b"
// output:
// all (5 <= i && i < 10)= true
nth
nthクエリ演算子は、これまでに抽出した値の中から、指定したインデックスにある要素を取得します。
// -------------------------------
// nth クエリ演算子のサンプル
let ls = [ 0..9 ]
query {
for i in ls do
nth 5 // lsの中から, 指定したインデックスにある要素を取得します.
}
|> printfn "nth 5= %d"
// output:
// nth 5= 5
query {
for i in ls do
where (5 <= i) // 5以上 の値を抽出します.
nth 2 // 現在選択中の要素の中から, 指定したインデックスにある要素を取得します.
}
|> printfn "nth 2= %d"
// output:
// nth 2= 7
// 選択している要素がない場合, System.ArgumentOutOfRangeException が throw されます.
query {
for i in ls do
where (i < 0) // 0未満 の値を抽出します.
nth 2
}
|> printfn "nth 2= %d"
// output:
// ハンドルされていない例外: System.ArgumentOutOfRangeException:
// 指定された引数は、有効な値の範囲内にありません。
where
whereクエリ演算子は、指定した条件に基づいて要素を抽出します。
// -------------------------------
// where クエリ演算子のサンプル
// 0~9のlist
let ls = [0..9]
query {
for i in ls do
where (i < 5) // listの中から [5未満の値] を抽出します.
}
|> Seq.toArray
|> printfn "where (i < 5)= %A"
// output:
// where (i < 5)= [|0; 1; 2; 3; 4|]
query {
for i in ls do
where (i = 5) // listの中から [5] と一致する値だけを抽出します.
}
|> Seq.toArray
|> printfn "where (i = 5)= %A"
// output:
// where (i = 5)= [|5|]
query {
for i in ls do
where (10 < i) // listの中から [10超過の値] を抽出します.
}
|> Seq.toArray
|> printfn "where (10 < i)= %A"
// output:
// where (10 < i)= [||]
select
selectクエリ演算子は、これまでに抽出した値の中にある必要な要素値を抽出することができます。
// -------------------------------
// select クエリ演算子のサンプル
[<Measure>]
type years
// サンプル用のrecord型
type Personal = { Name:string; Age:int<years>; }
let persons = [
{ Name="Alice"; Age=20<years>; }
{ Name="Bob"; Age=21<years>; }
{ Name="Cheryl"; Age=22<years>; }
{ Name="Daniel"; Age=23<years>; }
{ Name="Edward"; Age=24<years>; }
{ Name="Fernando"; Age=25<years>; }
]
query {
for p in persons do
select p.Name // Pesonal listの各要素の中から, Name要素のみを抽出します.
}
|> Seq.toArray
|> printfn "select p.Name array= %A"
// output:
// select p.Name array= [|"Alice"; "Bob"; "Cheryl"; "Daniel"; "Edward"; "Fernando"|]
query {
for p in persons do
select p.Age // Pesonal listの各要素の中から, Age要素のみを抽出します.
}
|> Seq.toArray
|> printfn "select p.Age array= %A"
// output:
// select p.Age array= [|20; 21; 22; 23; 24; 25|]
query {
for p in persons do
where (23<years> < p.Age) // 年齢が23歳よりも上の人物のみ抽出します
select p.Name // whereで抽出した人物の名前のみ抽出します
}
|> Seq.toArray
|> printfn "array= %A"
// output:
// array= [|"Edward"; "Fernando"|]
count
countクエリ演算子は、これまでに抽出した要素数を取得します。
// -------------------------------
// count クエリ演算子のサンプル
let ls = [ 0..9 ]
query {
for i in ls do
count // countだけ利用すると, 全要素数を取得可能です.
}
|> printfn "count= %d"
// output:
// count= 10
query {
for i in ls do
where (i < 5) // 5未満の値を抽出します.
count // whereで抽出した値の要素数を取得します.
}
|> printfn "count= %d"
// output:
// count= 5
head
headクエリ演算子は、これまでに抽出した要素の中から先頭の要素を取得します。
// -------------------------------
// head クエリ演算子のサンプル
let ls = [ 0..9 ]
query {
for i in ls do
head // 全要素の中から先頭の要素を取得可能です.
}
|> printfn "head= %d"
// output:
// head= 0
query {
for i in ls do
where (5 <= i) // 5以上の値を抽出します.
head // whereで抽出した要素の先頭を取得します.
}
|> printfn "head= %d"
// output:
// head= 5
query {
for i in ls do
where (10 < i) // 10超過の値を抽出します.
head // 要素がない場合, 例外が発生します.
}
|> printfn "head= %d"
// output:
// System.InvalidOperationException: シーケンスに要素が含まれていません.
headOrDefault
headOrDefaultクエリ演算子は、これまでに抽出した要素の中から先頭の要素を取得します。また、シーケンスに要素がない場合は、デフォルト値を返します。
// ------------------------------------
// headOrDefault クエリ演算子のサンプル
let ls = [ 0..9 ]
query {
for i in ls do
headOrDefault // 全要素の中から先頭の要素を取得可能です.
}
|> printfn "head= %d"
// output:
// head= 0
query {
for i in ls do
where (5 <= i) // 5以上の値を抽出します.
headOrDefault // whereで抽出した要素の先頭を取得します.
}
|> printfn "head= %d"
// output:
// head= 5
query {
for i in ls do
where (10 < i) // 10超過の値を抽出します.
headOrDefault // 要素がない場合, デフォルト値が得られます.
}
|> printfn "head= %d"
// output:
// head= 0
last
lastクエリ演算子は、これまでに抽出した要素の中から最後の要素を取得します。
// -------------------------------
// last クエリ演算子のサンプル
let ls = [ 0..9 ]
query {
for i in ls do
last // 全要素の最後の要素を取得可能です.
}
|> printfn "last= %d"
// output:
// last= 9
query {
for i in ls do
where (5 <= i) // 5以上の値を抽出します.
last // whereで抽出した要素の最終要素を取得します.
}
|> printfn "last= %d"
// output:
// last= 9
query {
for i in ls do
where (10 < i) // 10超過の値を抽出します.
last // 要素がない場合, 例外が発生します.
}
|> printfn "last= %d"
// output:
// System.InvalidOperationException: シーケンスに要素が含まれていません.
lastOrDefault
lastOrDefaultクエリ演算子は、これまでに抽出した要素の中から最後の要素を取得します。また、シーケンスに要素がない場合は、デフォルト値を返します。
// -------------------------------
// lastOrDefault クエリ演算子のサンプル
let ls = [ 0..9 ]
query {
for i in ls do
lastOrDefault // 全要素の最後の要素を取得可能です.
}
|> printfn "lastOrDefault= %d"
// output:
// last= 9
query {
for i in ls do
where (5 <= i) // 5以上の値を抽出します.
lastOrDefault // whereで抽出した要素の最終要素を取得します.
}
|> printfn "lastOrDefault= %d"
// output:
// last= 9
query {
for i in ls do
where (10 < i) // 10超過の値を抽出します.
lastOrDefault // 要素がない場合, デフォルト値が得られます.
}
|> printfn "lastOrDefault= %d"
// output:
// lastOrDefault= 0
exactlyOne
exactlyOneクエリ演算子は、選択されている要素が単一の場合にその要素を取得します。選択されている要素が複数存在するか、まったく存在しない場合には例外をthrowします。
// -------------------------------
// exactlyOne クエリ演算子のサンプル
[<Measure>] type old
type Person = { Name: string; Age: int<old>; }
let ls = [ { Name="alex"; Age=20<old>; }
{ Name="bob"; Age=21<old>; }
{ Name="carol"; Age=22<old>; }
{ Name="daniel"; Age=23<old>; } ]
query {
for p in ls do
where (p.Age = 21<old>) // 21歳のPersonのみ抽出.
exactlyOne // 現在選択している要素が一つのみの場合に, 値を返します.
}
|> printfn "exactlyOne= %A"
// output:
// exactlyOne= {Name = "bob"; Age = 21;}
query {
for p in ls do
where (p.Age < 20<old>) // 20歳未満のPersonを抽出
exactlyOne // 現在選択している要素が一つもない場合, 例外が発生します.
}
|> printfn "exactlyOne= %A"
// output:
// ハンドルされていない例外: System.InvalidOperationException:
// シーケンスに要素が含まれていません
query {
for i in ls do
exactlyOne // 要素が複数ある場合, 例外が発生します.
}
|> printfn "exactlyOne= %A"
// output:
// ハンドルされていない例外: System.InvalidOperationException:
// シーケンスに複数の要素が含まれています
exactlyOneOrDefault
exactlyOneクエリ演算子は、選択されている要素が単一の場合にその要素を取得します。選択している要素がまったく存在しない場合にはデフォルト値を返し、選択されている要素が複数存在する場合には例外をthrowします。
// ------------------------------------------
// exactlyOneOrDefault クエリ演算子のサンプル
[<Measure>] type old
type Person = { Name: string; Age: int<old>; }
let ls = [ { Name="alex"; Age=20<old>; }
{ Name="bob"; Age=21<old>; }
{ Name="carol"; Age=22<old>; }
{ Name="daniel"; Age=23<old>; } ]
query {
for p in ls do
where (p.Age = 21<old>) // 21歳のPersonのみ抽出.
exactlyOneOrDefault // 現在選択している要素が一つのみの場合に, 値を返します.
}
|> printfn "exactlyOneOrDefault= %A"
// output:
// exactlyOne= {Name = "bob"; Age = 21;}
query {
for p in ls do
where (p.Age < 20<old>) // 20歳未満のPersonを抽出
exactlyOneOrDefault // 現在選択している要素が一つもない場合, デフォルト値を返します.
}
|> printfn "exactlyOneOrDefault= %A"
// output:
// exactlyOneOrDefault= <null>
query {
for i in ls do
exactlyOneOrDefault // 要素が複数ある場合, 例外が発生します.
}
|> printfn "exactlyOneOrDefault= %A"
// output:
// ハンドルされていない例外: System.InvalidOperationException:
// シーケンスに複数の要素が含まれています
minBy
minByクエリ演算子は、選択されている要素の中から最小の値を取得します。
// -------------------------------------
// minBy クエリ演算子のサンプル
let ls = [ 0..9 ]
query {
for i in ls do
minBy i
}
|> printfn "minBy= %d"
// output:
// minBy= 0
query {
for i in ls do
where (5 <= i) // 5以上の値を抽出
minBy i
}
|> printfn "minBy= %d"
// output:
// minBy= 5
query {
for i in ls do
where (i < 0) // 0未満の値を抽出
minBy i // 現在選択している要素が一つもない場合, 例外が発生します.
}
|> printfn "minBy= %d"
// output:
// ハンドルされていない例外: System.InvalidOperationException:
// シーケンスに要素が含まれていません
minByNullable
minByNullableクエリ演算子は、Null許容型の要素に対して利用することができ、選択されている要素の中から最小の値を取得します。その際nullは無視されます。
// -------------------------------------
// minByNullable クエリ演算子のサンプル
open System
let ls = [ Nullable(1)
Nullable()
Nullable(2)
Nullable(4)
Nullable()
Nullable(9)
Nullable(12) ]
query {
for i in ls do
minByNullable i
}
|> printfn "minByNullable= %A"
// output:
// minByNullable= 1
query {
for i in ls do
where (if i.HasValue then 3 <= i.Value else false) // 3以上の値を抽出
minByNullable i
}
|> printfn "minByNullable= %A"
// output:
// minByNullable= 4
query {
for i in ls do
where (if i.HasValue then i.Value < 0 else false) // 0未満の値を抽出
minByNullable i
}
|> printfn "minByNullable= %A"
// output:
// minByNullable= <null>
maxBy
maxByクエリ演算子は、選択されている要素の中から最大の値を取得します。
// -------------------------------------
// maxBy クエリ演算子のサンプル
let ls = [ 0..9 ]
query {
for i in ls do
maxBy i // 最大値を取得
}
|> printfn "maxBy= %A"
// output:
// maxBy= 9
query {
for i in ls do
where (3 <= i && i < 8) // 3以上 かつ 8未満 の値を抽出
maxBy i // 現在抽出している要素の中で最大の値を取得
}
|> printfn "maxBy= %A"
// output:
// maxBy= 7
query {
for i in ls do
where (i < 0) // 0未満の値を抽出
maxBy i // 要素数が0の場合は, 例外が発生します
}
|> printfn "maxBy= %A"
// output:
// ハンドルされていない例外: System.InvalidOperationException:
// シーケンスに要素が含まれていません
maxByNullable
maxByNullableクエリ演算子は、Null許容型の要素に対して利用することができ、選択されている要素の中から最大の値を取得します。その際nullは無視されます。
// -------------------------------------
// maxByNullable クエリ演算子のサンプル
open System
let ls = [ Nullable(1)
Nullable()
Nullable(2)
Nullable(4)
Nullable()
Nullable(9)
Nullable(12) ]
query {
for i in ls do
maxByNullable i
}
|> printfn "maxByNullable= %A"
// output:
// maxByNullable= 12
query {
for i in ls do
where (if i.HasValue then i.Value < 10 else false) // 10未満の値を抽出
maxByNullable i
}
|> printfn "maxByNullable= %A"
// output:
// maxByNullable= 9
query {
for i in ls do
where (if i.HasValue then i.Value < 0 else false) // 0未満の値を抽出
maxByNullable i
}
|> printfn "maxByNullable= %A"
// output:
// maxByNullable= <null>
sumBy
sumByクエリ演算子は、選択されている要素の合計値を取得します。
// -------------------------------------
// sumBy クエリ演算子のサンプル
let ls = [ 0..9 ]
query {
for i in ls do
sumBy i
}
|> printfn "sumBy= %d"
// output:
// sumBy= 45
query {
for i in ls do
where (5 <= i) // 5以上の値を抽出
sumBy i // 抽出した値を合計
}
|> printfn "sumBy= %d"
// output:
// sumBy= 35
query {
for i in ls do
where (i < 0) // 0未満の値を抽出
sumBy i // 対象要素が0の場合, 0を返します
}
|> printfn "sumBy= %d"
// output:
// sumBy= 0
sumByNullable
sumByNullableクエリ演算子は、Null許容型の要素に対して利用することができ、選択されている要素の合計値を取得します。その際nullは無視されます。
// -------------------------------------
// sumByNullable クエリ演算子のサンプル
open System
let ls = [ Nullable(1)
Nullable()
Nullable(2)
Nullable(4)
Nullable()
Nullable(9)
Nullable(12) ]
query {
for i in ls do
sumByNullable i
}
|> printfn "sumByNullable= %A"
// output:
// sumByNullable= 28
query {
for i in ls do
where (if i.HasValue then i.Value < 10 else false) // 10未満の値を抽出
sumByNullable i
}
|> printfn "sumByNullable= %A"
// output:
// sumByNullable= 16
query {
for i in ls do
where (if i.HasValue then i.Value < 0 else false) // 0未満の値を抽出
sumByNullable i
}
|> printfn "sumByNullable= %A"
// output:
// sumByNullable= 0
averageBy
averageByクエリ演算子は、選択されている要素の平均値を取得します。
// -------------------------------------
// averageBy クエリ演算子のサンプル
let ls = [ 0..9 ]
query {
for i in ls do
averageBy (float i)
}
|> printfn "averageBy= %f"
// output:
// averageBy= 4.500000
query {
for i in ls do
where (5 <= i) // 5以上の値を抽出
averageBy (float i) // 抽出した値を合計
}
|> printfn "averageBy= %f"
// output:
// averageBy= 7.000000
query {
for i in ls do
where (i < 0) // 0未満の値を抽出
averageBy (float i) // 対象要素が0の場合, 例外が発生します
}
|> printfn "averageBy= %f"
// output:
// ハンドルされていない例外: System.InvalidOperationException: source
averageByNullable
averageByNullableクエリ演算子は、Null許容型の要素に対して利用することができ、選択されている要素の平均値を取得します。その際nullは無視されます。
// -------------------------------------
// averageByNullable クエリ演算子のサンプル
open System
let ls = [ Nullable(1.)
Nullable()
Nullable(2.)
Nullable(4.)
Nullable()
Nullable(9.)
Nullable(12.) ]
query {
for i in ls do
averageByNullable i
}
|> printfn "averageByNullable= %A"
// output:
// averageByNullable= 4.0
query {
for i in ls do
where (if i.HasValue then i.Value < 10. else false) // 10未満の値を抽出
averageByNullable i
}
|> printfn "averageByNullable= %A"
// output:
// averageByNullable= 4.0
query {
for i in ls do
where (if i.HasValue then i.Value < 0. else false) // 0未満の値を抽出
averageByNullable i
}
|> printfn "averageByNullable= %A"
// output:
// averageByNullable=
groupBy
groupByクエリ演算子は、選択されている要素を、指定したキーセレクターに従ってグループ化します。
// -------------------------------------
// groupBy クエリ演算子のサンプル
type Person = { ID: string; Name: string; Age: int; }
let persons = [ { ID="0x00"; Name="Alice"; Age=22}
{ ID="0x00"; Name="Bob"; Age=23}
{ ID="0x01"; Name="Chris"; Age=32}
{ ID="0x01"; Name="Edward"; Age=45}
{ ID="0x02"; Name="Felix"; Age=26} ]
query {
for p in persons do
groupBy p.ID into g // Person.IDでグループ化
select g
}
|> printfn "groupBy= %A"
// output: ID毎にグループ化されていることがわかります.
// groupBy= [seq [{ID = "0x00";
// Name = "Alice";
// Age = 22;};
// {ID = "0x00";
// Name = "Bob";
// Age = 23;}];
// seq [{ID = "0x01";
// Name = "Chris";
// Age = 32;};
// {ID = "0x01";
// Name = "Edward";
// Age = 45;}];
// seq [{ID = "0x02";
// Name = "Felix";
// Age = 26;}]]
query {
for p in persons do
groupBy p.ID into g // Person.IDでグループ化
select g.Key // Keyとなった値のみを抽出
}
|> printfn "groupBy= %A"
// output: Key値が重複なしで取得可能です.
// groupBy= seq ["0x00"; "0x01"; "0x02"]
sortBy
sortByクエリ演算子は、選択されている要素を、昇り順にソートしたシーケンスを取得します。
// -------------------------------------
// sortBy クエリ演算子のサンプル
let ls = [ 5; 9; 6; 3; 2; 0; 4; 1; 7; 8; ]
query {
for l in ls do
sortBy l // 昇り順にソート
}
|> Seq.toList
|> printfn "sortBy= %A"
// output:
// sortBy= [0; 1; 2; 3; 4; 5; 6; 7; 8; 9]
// 元のリストには影響がないことが確認できます.
ls |> printfn "sortBy= %A"
// output:
// sortBy= [5; 9; 6; 3; 2; 0; 4; 1; 7; 8]
query {
for l in ls do
where (l < 6) // 6未満の値を抽出
sortBy l // 昇り順にソート
}
|> Seq.toList
|> printfn "sortBy= %A"
// output:
// sortBy= [0; 1; 2; 3; 4; 5]
query {
for l in ls do
where (l < 0) // 0未満の値を抽出
sortBy l
}
|> Seq.toList
|> printfn "sortBy= %A"
// output:
// sortBy= []
sortByDescending
sortByDescendingクエリ演算子は、選択されている要素を、降り順にソートしたシーケンスを取得します。
// -------------------------------------
// sortByDescending クエリ演算子のサンプル
let ls = [ 5; 9; 6; 3; 2; 0; 4; 1; 7; 8; ]
query {
for l in ls do
sortByDescending l // 降り順にソート
}
|> Seq.toList
|> printfn "sortByDescending= %A"
// output:
// sortByDescending= [9; 8; 7; 6; 5; 4; 3; 2; 1; 0]
// 元のリストには影響がないことが確認できます.
ls |> printfn "sortByDescending= %A"
// output:
// sortByDescending= [5; 9; 6; 3; 2; 0; 4; 1; 7; 8]
query {
for l in ls do
where (l < 6) // 6未満の値を抽出
sortByDescending l // 降り順にソート
}
|> Seq.toList
|> printfn "sortByDescending= %A"
// output:
// sortByDescending= [5; 4; 3; 2; 1; 0]
query {
for l in ls do
where (l < 0) // 0未満の値を抽出
sortByDescending l
}
|> Seq.toList
|> printfn "sortByDescending= %A"
// output:
// sortByDescending= []
sortByNullable
sortByNullableクエリ演算子は、選択されているnull許容の要素を、昇り順にソートしたシーケンスを取得します。その際nullは無視されません。
// -------------------------------------
// sortByNullable クエリ演算子のサンプル
open System
let ls = [ Nullable(10.)
Nullable()
Nullable(0.)
Nullable(6.)
Nullable(4.)
Nullable()
Nullable(1.)
Nullable(12.) ]
query {
for i in ls do
sortByNullable i
}
|> Seq.toList
|> printfn "sortByNullable= %A"
// output:
// sortByNullable= [null; null; 0.0; 1.0; 4.0; 6.0; 10.0; 12.0]
query {
for i in ls do
where (if i.HasValue then i.Value < 10. else false) // 10未満の値を抽出
sortByNullable i
}
|> Seq.toList
|> printfn "sortByNullable= %A"
// output:
// sortByNullable= [0.0; 1.0; 4.0; 6.0]
query {
for i in ls do
where (if i.HasValue then i.Value < 0. else false) // 0未満の値を抽出
sortByNullable i
}
|> Seq.toList
|> printfn "sortByNullable= %A"
// output:
// sortByNullable= []
sortByNullableDescending
sortByNullableDescendingクエリ演算子は、選択されているnull許容の要素を、降り順にソートしたシーケンスを取得します。その際nullは無視されません。
// -------------------------------------
// sortByNullableDescending クエリ演算子のサンプル
open System
let ls = [ Nullable(10.)
Nullable()
Nullable(0.)
Nullable(6.)
Nullable(4.)
Nullable()
Nullable(1.)
Nullable(12.) ]
query {
for i in ls do
sortByNullableDescending i
}
|> Seq.toList
|> printfn "sortByNullableDescending= %A"
// output:
// sortByNullableDescending= [12.0; 10.0; 6.0; 4.0; 1.0; 0.0; null; null]
query {
for i in ls do
where (if i.HasValue then i.Value < 10. else false) // 10未満の値を抽出
sortByNullableDescending i
}
|> Seq.toList
|> printfn "sortByNullableDescending= %A"
// output:
// sortByNullableDescending= [6.0; 4.0; 1.0; 0.0]
query {
for i in ls do
where (if i.HasValue then i.Value < 0. else false) // 0未満の値を抽出
sortByNullableDescending i
}
|> Seq.toList
|> printfn "sortByNullableDescending= %A"
// output:
// sortByNullableDescending= []
skip
skipクエリ演算子は、選択されている要素の先頭要素から指定した数分スキップしたシーケンスを取得します。
// -------------------------------------
// skip クエリ演算子のサンプル
let ls = [ 5; 9; 6; 3; 2; 0; 4; 1; 7; 8; ]
query {
for l in ls do
skip 3 // 先頭要素から3要素分スキップ
}
|> Seq.toList
|> printfn "skip 3= %A"
// output:
// skip 3= [3; 2; 0; 4; 1; 7; 8]
query {
for l in ls do
sortBy l // 昇順にソート
skip 5 // 先頭要素から5要素分スキップ
}
|> Seq.toList
|> printfn "sortBy l >> skip 5= %A"
// output:
// sortBy l >> skip 5= [5; 6; 7; 8; 9]
query {
for l in ls do
where (l < 0) // 0未満の値を抽出
skip 3 // 対象要素が0の場合でも, 例外は発生しない
}
|> Seq.toList
|> printfn "where (l < 0) >> skip 3= %A"
// output:
// where (l < 0) >> skip 3= []