Swift使用LINQ操作数组/集合(附Swift的LINQ扩展、及替代方法)

一,什么是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

时间: 2024-08-02 15:25:13

Swift使用LINQ操作数组/集合(附Swift的LINQ扩展、及替代方法)的相关文章

LINQ操作数组代码(交集,并集,差集,最值,平均,去重复)_实用技巧

下面以数组为例,展示一些常用LINQ操作. 复制代码 代码如下: static void Main(string[] args) { int[] a = { 1, 2, 3, 4, 5, 6, 7 }; int[] b = { 4, 5, 6, 7, 8, 9, 10 }; int[] c = { 1, 2, 3, 3, 4, 1, 2, 4, 6, 1, 6, 5 }; // 交集 var fuck = a.Intersect(b); // 并集 var shit = a.Union(b);

CI框架AR操作(数组形式)实现插入多条sql数据的方法_php实例

本文实例讲述了CI框架AR操作实现插入多条sql数据的方法.分享给大家供大家参考,具体如下: 如果你不使用AR的话,你可以这样做: INSERT INTO TABLE (FIELDS) VALUES ('1','2'),('3','4'); $this->db->query($sql); 个人还是喜欢CI的AR操作,老版本(2.0一下)应该没有插入多条数据的操作,新版本可以用: $this->db->insert_batch(); 如下案例: $data = array( arra

CI框架AR操作(数组形式)实现插入多条sql数据的方法

本文实例讲述了CI框架AR操作实现插入多条sql数据的方法.分享给大家供大家参考,具体如下: 如果你不使用AR的话,你可以这样做: INSERT INTO TABLE (FIELDS) VALUES ('1','2'),('3','4'); $this->db->query($sql); 个人还是喜欢CI的AR操作,老版本(2.0一下)应该没有插入多条数据的操作,新版本可以用: $this->db->insert_batch(); 如下案例: $data = array( arra

json数组-SWIFT 如何解析 JSON数组

问题描述 SWIFT 如何解析 JSON数组 [{"Date(time)":"2015-12-01","DayOfWeek(time)":"3","Time(time)":"11:38:23","Hour(time)":"11"}, {"Date(time)":"2015-12-02","DayOf

Swift HTTP网络操作库Alamofire实现文件上传详解

六,使用Alamofire进行文件上传 1,Alamofire支持如下上传类型: File Data Stream MultipartFormData 2,使用文件流的形式上传文件 let fileURL = NSBundle.mainBundle().URLForResource("hangge", withExtension: "zip")   Alamofire.upload(.POST, "http://www.hangge.com/upload.

[译] Swift 上的高性能数组

本文讲的是Swift 上的高性能数组, 原文地址:On Performant Arrays in Swift 原文作者:JORDAN SMITH 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m- 译者:jingzhilehuakai 校对者:RickeyBoy cbangchen Swift 上的高性能数组 对于日常应用开发,考虑数组性能是一件不会经常发生的事.如果你正在实现需要扩展的算法,也许高性能数组就能出现在你脑海中.也许你正在写更偏向于底层的代码,比如

Swift HTTP网络操作库Alamofire实现文件下载,断点续传例子

七,使用Alamofire进行文件下载 1,自定义下载文件的保存目录 下面代码将logo图片下载下来保存到用户文档目录下(Documnets目录),文件名不变. Alamofire.download(.GET, "yun_qi_img/logo.png") {     temporaryURL, response in     let fileManager = NSFileManager.defaultManager()     let directoryURL = fileMana

使用 foreach 操作数组

使用 foreach 操作数组 foreach 并不是 Java 中的关键字,是 for 语句的特殊简化版本,在遍历数组.集合时, foreach 更简单便捷.从英文字面意思理解 foreach 也就是" for 每一个"的意思,那么到底怎么使用 foreach 语句呢? 语法: 我们分别使用 for 和 foreach 语句来遍历数组 运行结果: 看到 foreach 的方便了吧!! 留个思考问题给大家:如果想在 foreach 语句中获取数组元素的下标,该如何做呢?? 任务 在编辑

Java数组/集合性能优化

1. 复制数组元素,使用System类arraycopy()方法替代循环赋值在数组之间复制元素 建议:System类arraycopy()方法复制数组元素 杜绝:循环赋值复制数组元素 原因: System类arraycopy()方法调用操作系统更底层函数,效率更高. 注:通过实测,在元素数量达到亿级别,两者都在几百毫秒,都很快,System类arraycopy()比循环赋值性能仅快1倍,但仍推荐使用System类arraycopy(). 2.避免创建集合不设置初始容量 使用集合(List.Set