KVC Collection Operators

2024-02-18 15:08
文章标签 collection kvc operators

本文主要是介绍KVC Collection Operators,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


Mattt Thompson撰写、 Candyan翻译

Ruby爱好者总爱嘲笑Objective-C臃肿的语法。

尽管新的Object Literals特性让我们的语法瘦了几斤,但那些红头发的恶霸们还总是用他们的单行map和花哨的Symbol#to_proc来嘲讽我们。

实际上,一门语言是否优雅归结起来就是其怎么样能更好的避免循环。forwhile语句是一种拖累;即使是快速枚举也一样。无论你怎么样使他们看起来更加的友好,循环依然是一个在自然语言中用非常简单方式描述所做事情的代码块

"给我这个列表里面所有员工的平均薪酬",等等。。。

Objective-C
double totalSalary = 0.0;
for (Employee *employee in employees) {totalSalary += [employee.salary doubleValue];
}
double averageSalary = totalSalary / [employees count];

╮(╯_╰)╭

幸运的是,键-值编码给我们了一种更加简洁的,几乎像Ruby一样的方式来做这件事:

Objective-C
[employees valueForKeyPath:@"@avg.salary"];

KVC集合运算符允许在valueForKeyPath:方法中使用key path符号在一个集合中执行方法。无论什么时候你在key path中看见了@,它都代表了一个特定的集合方法,其结果可以被返回或者链接,就像其他的key path一样。

集合运算符会根据其返回值的不同分为以下三种类型:

  • 简单的集合运算符 返回的是strings, number, 或者 dates
  • 对象运算符 返回的是一个数组
  • 数组和集合运算符 返回的是一个数组或者集合

要理解其工作原理,最好方式就是去action里面看看。想象一个Product类和一个由以下数据所组成的products数组:

Objective-C
@interface Product : NSObject
@property NSString *name;
@property double price;
@property NSDate *launchedOn;
@end

键-值 编码会在必要的时候把基本数据类型的数据自动装箱和拆箱到NSNumber或者NSValue中来确保一切工作正常。

Name Price Launch Date
iPhone 5 $199 September 21, 2012
iPad Mini $329 November 2, 2012
MacBook Pro $1699 June 11, 2012
iMac $1299 November 2, 2012

简单集合操作符

  • @count: 返回一个值为集合中对象总数的NSNumber对象。
  • @sum: 首先把集合中的每个对象都转换为double类型,然后计算其总,最后返回一个值为这个总和的NSNumber对象。
  • @avg: Takes the double value of each object in the collection, and returns the average value as an NSNumber.
  • @max: 使用compare:方法来确定最大值。所以为了让其正常工作,集合中所有的对象都必须支持和另一个对象的比较。
  • @min: 和@max一样,但是返回的是集合中的最小值。

例如

Objective-C
[products valueForKeyPath:@"@count"]; // 4
[products valueForKeyPath:@"@sum.price"]; // 3526.00
[products valueForKeyPath:@"@avg.price"]; // 881.50
[products valueForKeyPath:@"@max.price"]; // 1699.00
[products valueForKeyPath:@"@min.launchedOn"]; // June 11, 2012

Pro提示:你可以简单的通过把self作为操作符后面的key path来获取一个由NSNumber组成的数组或者集合的总值,例如[@[@(1), @(2), @(3)] valueForKeyPath:@"@max.self"] (/感谢 @davandermobile, 来自 Objective Sea)

对象操作符

想象下,我们有一个inventory数组,代表了当地苹果商店的当前库存(iPad Mini不足,并且没有新的iMac,因为还没有发货):

Objective-C
NSArray *inventory = @[iPhone5, iPhone5, iPhone5, iPadMini, macBookPro, macBookPro];
  • @unionOfObjects / @distinctUnionOfObjects: 返回一个由操作符右边的key path所指定的对象属性组成的数组。其中@distinctUnionOfObjects 会对数组去重, 而且@unionOfObjects 不会.

例如

Objective-C
[inventory valueForKeyPath:@"@unionOfObjects.name"]; // "iPhone 5", "iPhone 5", "iPhone 5", "iPad Mini", "MacBook Pro", "MacBook Pro"
[inventory valueForKeyPath:@"@distinctUnionOfObjects.name"]; // "iPhone 5", "iPad Mini", "MacBook Pro"

数组和集合操作符

数则和集合操作符跟对象操作符很相似,只不过它是在NSArrayNSSet所组成的集合中工作的。如果我们做一些例如:比较几个商店中的库存(和我们上一节类似的appleStore库存和买iPhone 5和iPad Mini的versizonStore库存)这样的工作,这个就会很有用。

  • @distinctUnionOfArrays / @unionOfArrays: 返回了一个数组,其中包含这个集合中每个数组对于这个操作符右面指定的key path进行操作之后的值。正如你期望的,distinct版本会移除重复的值。

  • @distinctUnionOfSets: 和@distinctUnionOfArrays差不多, 但是它期望的是一个包含着NSSet对象的NSSet,并且会返回一个NSSet对象。因为集合不能包含重复的值,所以它只有distinct操作。

例如

Objective-C
[@[appleStoreInventory, verizonStoreInventory] valueForKeyPath:@"@distinctUnionOfArrays.name"]; // "iPhone 5", "iPad Mini", "MacBook Pro"

这可能是一个可怕的想法

令人好奇的是,苹果的KVC集合操作符文档冒出了下面这个提示:

注意: 目前还不能自定义集合操作符。

这个提示是有意义的,因为大多数人在第一次看到集合运算符时都在想这个。

然而,事实证明,在我们的小伙伴objc/runtime的帮助下,这个实际上  有可以能的实现的。

Guy English有一篇很神奇的文章,在文章中,他swizzles valueForKeyPath:来解析自定义的DSL,其扩展了一些有趣的效果:

Objective-C
NSArray *names = [allEmployees valueForKeyPath: @"[collect].{daysOff<10}.name"];

这段代码可以得到只有休了不足10天假期的人的名字(无疑是要提醒他们去休个假吧!)

或者,来看个可笑的极端情况:

Objective-C
NSArray *albumCovers = [records valueForKeyPath:@"[collect].{artist like 'Bon Iver'}.<NSUnarchiveFromDataTransformerName>.albumCoverImageData"];

Ruby小伙伴们羡慕吧。只用一行就在艺人记录中过滤出来了名字叫"Bon Iver"的艺人,并且用匹配到的专辑的专辑封面的图像数据初始化了一个NSImage对象。

这是一个好的想法吗?可能不是。(NSPredicate更加合适,并且其使得逻辑更加简单,易懂)

这个很酷吗?当然啦!这个聪明的例子展示了Objective-C DSL和元编程未来可能的发展方向。


KVC集合运算符是一个想节省几行代码并在这一过程中看起来很酷的人必须要了解的。当像Ruby这样的脚本语言自夸它的单行能力是多么的灵活时,我们也许应该花一点儿时间来庆祝Objective-C中的约束和集合操作符。毕竟,Ruby非常非常慢,我说的对吗?</troll>

作者 Mattt Thompson
Mattt Thompson

Mattt Thompson (@mattt) is the creator & maintainer of AFNetworking and other popular open-source projects, includingPostgres.app, ASCIIwwdc and Nomad.

翻译者

这篇关于KVC Collection Operators的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/721548

相关文章

红队内网攻防渗透:内网渗透之内网对抗:横向移动篇Kerberos委派安全RBCD资源Operators组成员HTLMRelay结合

基于资源的约束委派(RBCD)是在Windows Server 2012中新加入的功能,与传统的约束委派相比,它不再需要域管理员权限去设置相关属性。RBCD把设置委派的权限赋予了机器自身,既机器自己可以决定谁可以被委派来控制我。也就是说机器自身可以直接在自己账户上配置msDS-AllowedToActOnBehalfOfOtherIdentity属性来设置RBCD。 所以核心就是谁或什么权限能修改

iOS OC底层面试题(KVC(Key-value coding)

KVC(Key-value coding) -(id)valueForKey:(NSString *)key;-(void)setValue:(id)value forKey:(NSString *)key; KVC就是指iOS的开发中,可以允许开发者通过Key名直接访问对象的属性,或者给对象的属性赋值。而不需要调用明确的存取方法。这样就可以在运行时动态地访问和修改对象的属性。而不是在编译时

mybatis中collection的使用(三级联动)

mybatis中association和collection的column传入多个参数值 项目中在使用association和collection实现一对一和一对多关系时需要对关系中结果集进行筛选,如果使用懒加载模式,即联合使用select标签时,主sql和关系映射里的sql是分开的,查询参数传递成为问题。 mybatis文档: propertydescriptioncolumn数据库的列名

Swift Combine — Operators(常用Filtering类操作符介绍)

目录 filter(_: )tryFilter(_: )compactMap(_: )tryCompactMap(_: )removeDuplicates()first(where:)last(where:) Combine中对 Publisher的值进行操作的方法称为 Operator(操作符)。 Combine中的 Operator通常会生成一个 Publisher,

KVC模式讲解和Block语法

KVC键值编码,使用完整实例: #import <Foundation/Foundation.h> @interface Course : NSObject {     NSString* courseName; } - (NSString*)description; @end   #import "Course.h" @implementation Course - (NS

iphone新手上路: KVC模式和iPhone基本控件的使用

MVC是一种设计模式,所谓设计模式就是解决某一特定问题的方案。 MVC是解决具有UI的应用系统的成熟解决方案,在Cocoa应用系统中严格按照该模式实现。 M-Model(模型)是应用系统中与视图对于部分的数据。 V-View(视图)是应用系统中用户看到并与之交互的界面。 C-Controller(控制器)是应用系统中起到控制器作用,接受用户事件,显示数据等,与视图进行交互等。 采用MVC

KVC设计模式讲解

在Objective-c语言中,可以用@property和@synthesize来创建实例变量的属性,因此对象访问的时候可以直接使用点语法。         但是,如果不声明属性,如何访问到对象的实例变量呢?KVC就解决了这一问题。         KVC  全称Key-Value-Coding,也就是键值编码。先看下面一个例子:  @interface  Student

About interview Questions Collection(Basic,Intermediate and Advanced) in MySQL

Basic MySQL Interview Questions 1.What is Mysql? Database management system for web servers 2.What are some of the advantages of using MySQL? FlexibilityPowerEnterprise-Level SQL FeatureFull-Text

单列集合顶层接口Collection及五类遍历方式(迭代器)

collection add方法细节: remove方法细节: contains方法细节: 如果集合中存储的是自定义对象, student之类的, 也想通过contains进行判断, 就必须在javaBean中重写equals方法 contains在arrayList中源代码:在底层调用了equals方法 重写: 一些回顾equals知识: st

Java 集合(Collection)

1、集合类概述 java.util包中就包含了一系列重要的集合类,而对于集合类,主要需要掌握的就是它的内部结构,以及遍历集合的迭代模式。 Java2的集合框架,抽其核心,主要有三种:List、Set和Map。如下图所示:  Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set Map