一,什麼是LINQ
LINQ 是 Language Integrated Query(語言集成查詢)的簡稱。它是微軟在.NET 3.5中引入的重要功能。既然是微軟推出的,那對應的編程言自然是c#和Visual Basic語言。
1,LINQ的作用
讓我們可以使用相同API(類似SQL的語法來查詢)操作不同的數據源。比如:SQL Server、Oracle、XML以及內存中的數據集合,當然開發人員也可以使用其提供的擴展框架添加更多的數據源。
2,LINQ的查詢操作符
LINQ定義了大約40個查詢操作符,如select、from、in、where以及order by(C#中)等。使用這些操作符可以編寫查詢語句。
3,LINQ的操作語法
LINQ查詢時有兩種語法可供選擇:查詢方法語法(Fluent Syntax)和查詢表達式(Query Expression)。
查詢方法方式:主要利用System.Linq.Enumerable類中定義的擴展方法和Lambda表達式方式進行查詢。
查詢語句方式:一種更接近SQL語法的查詢方式,可讀性更好。
4,LINQ的使用樣例
下面以使用LINQ操作內存中的數據集合為例。
比如我們有一個聯系人的集合,裡面聯系人有姓名、年齡、電話這三個屬性。我們只想要查出年齡在40歲以下的人員,同時返回的結果集裡只需要聯系人姓名和年齡即可(注意,這裡我們不需要電話)。
那麼組合使用where語句和select語句即可,對應的C#代碼如下(以查詢方法語法為例):
var user1 = new User(){ name = "張三", age = 34, phone = "123456" };
var user2 = new User(){ name = "李四", age = 10, phone = "101" };
var user3 = new User(){ name = "王五", age = 45, phone = "110" };
List<User> userCollection = new List<User>() { user1, user2, user3 };
var results = userCollection
.Where(c => c.age < 40)
.Select(c => new { c.name, c.age });
foreach (var result in results)
{
Console.WriteLine(result.ToString());
}
Console.ReadLine();
二,Swift對LINQ的支持情況
雖然LINQ簡單、高效、強大,但由於是.Net上的東西,所以在Swift中無法使用LINQ查詢。好在我們可以通過 map、filter、reduce 配合閉包循環來實現類似的功能。
1,還是以上面的聯系人樣例為例,在Swift中要實現同樣的功能可以這麼寫:
let userCollection = [
(name: "張三", age: 34, phone: "123456"),
(name: "李四", age: 10, phone: "101"),
(name: "王五", age: 45, phone: "110")]
let results = userCollection.lazy
.filter { c in c.age < 45 }
.map { ($0.name, $0.age) }
for result in results {
print(result)
}
2,更多的樣例
可以查看GitHub上的一個項目:101 LINQ Samples in Swift 2.0
它提供了一百多個樣例,演示了各種LINQ查詢在Swift中的替換方法,大家可以去看下。
三,給Swift添加LINQ擴展
有時單純地使用map、filter、reduce已經不能滿足我們的需求,好在網上有大神提供了相關的三方庫,讓我們在Swift中也能很方便的使用LINQ。下面介紹個人覺得比較優秀擴展庫:SINQ。
1,SINQ介紹
顧名思義,SINQ 就是 Swift Integrated Query 的縮寫,當然我們也可以稱它為 LINQ for Swift。
SINQ使用方式類似於LINQ的查詢方法語法(Fluent Syntax),它提供了大量的查詢方法,比如:aggregate/reduce, all, any, concat, contains, count, distinct, each, elementAt, except, first, groupBy, groupJoin, intersect, join, last, min/max, argmin/argmax, orderBy, reverse, select map, selectMany, single, skip, take, thenBy/thenByDescending, toArray, toDictionary/toLookupDictionary, union, whereTrue/filter, zip
2,SINQ的安裝配置
GitHub地址:https://github.com/slazyk/SINQ
下載後把其中的 SINQ.swift 添加到工程裡面即可。
3,SINQ的使用樣例
(1)whereTrue 與 select 方法
還是實現上面的同樣的功能,查出年齡在40歲以下的人員,同時返回的結果集裡只需要聯系人姓名和年齡。
let userCollection = [
(name: "張三", age: 34, phone: "123456"),
(name: "李四", age: 10, phone: "101"),
(name: "王五", age: 45, phone: "110")]
let results = sinq(userCollection)
.whereTrue{ $0.age < 40 }
.select{ ($0.name, $0.age) }
for result in results {
print(result)
}
(2)orderBy / orderByDescending 排序方法
查出年齡在40歲以下的人員,同時按照年齡進行升序排列。
let results = sinq(userCollection)
.whereTrue{ $0.age < 40 }
.orderBy{ $0.age }
(3)min / max 取最小最大值方法
查詢所有聯系人中的最小年齡。
let result = sinq(userCollection).min{ $0.age }
print(result) // 10
(4)argmin / argmax 取得包含最小最大值的元素對象
查詢出最小年齡的聯系人。
let result = sinq(userCollection).argmin{ $0.age }
print(result) // ("李四", 10, "101")
(5)skip 跳過固定數量的元素,take獲取固定數量的元素
查詢出第2個和第3個聯系人。
let results = sinq(userCollection).skip(1).take(2)
for result in results {
print(result)
}
//("李四", 10, "101")
//("王五", 45, "110")
(6)all 判斷所有元素是否都滿足條件
判斷所有聯系人年齡是否都是小於40歲。
let result = sinq(userCollection).all{ $0.age < 40 }
print(result) //false
(7)any 判斷是否存在滿足條件元素
判斷聯系人中是否有年齡小於40歲的。
let result = sinq(userCollection).any{ $0.age < 40 }
print(result) //true