今天看一个K线的库,看到了用数组的
valueForKeyPath
求数组中某个字段的平均值,没有用到for循环,之前我是没这样用过的,于是决定研究一下这个valueForKeyPath
。
数组的valueForKeyPath
之前我了解的valueForKeyPath
一直以为可以对多层字典取值,或者对对象的多层取值,其实不然,数组也是可以用的,而且功能很有意思,也很实用
1. 取数组元素中某个keyPath组成新数组返回
代码如下:
NSArray *arr = @[
@{
@"id": @"1",
@"name": @"小明",
@"dog": @{
@"name": @"欢欢"
}
},
@{
@"id": @"2",
@"name": @"小红",
@"dog": @{
@"name": @"乐乐"
}
},
@{
@"id": @"3",
@"name": @"小王",
@"dog": @{
@"name": @"妞妞"
}
},
];
NSArray *nameArr = [arr valueForKeyPath:@"name"];
NSArray *dogNameArr = [arr valueForKeyPath:@"dog.name"];
NSLog(@"打印 名字:%@", nameArr);
NSLog(@"打印 狗名字:%@", dogNameArr);
打印结果:
打印 名字:[
"小明",
"小红",
"小王"
]
打印 狗名字:[
"欢欢",
"乐乐",
"妞妞"
]
2. 数组中元素批量调用某方法
代码及打印如下:
// 代码
NSArray *arr = @[@"aaa", @"bbb", @"ccc"];
NSLog(@"%@", [arr valueForKeyPath:@"uppercaseString"]);
// 打印结果
[
"AAA",
"BBB",
"CCC"
]
3. 数组求和@sum
,平均数@avg
,最大值@max
,最小值@min
3.1. 不指定类型: 不指定类型时,数组中的元素需要时同一类型,否则崩溃
NSArray *array = @[@1, @2, @3, @4];
NSNumber *sum = [array valueForKeyPath:@"@sum.self"];
NSNumber *avg = [array valueForKeyPath:@"@avg.self"];
NSNumber *max = [array valueForKeyPath:@"@max.self"];
NSNumber *min = [array valueForKeyPath:@"@min.self"];
NSLog(@"%@", @[sum, avg, max, min]);
打印结果:
[
10,
2.5,
4,
1
]
3.2. 指定输出类型: 指定输出类型时,数组中元素可以不同类型,甚至可以不是数字,非数字的按0算
NSArray *array = @[@1, @"2", @3, @4, @"呵呵"];
NSNumber *sum_f = [array valueForKeyPath:@"@sum.floatValue"];
NSNumber *avg_f = [array valueForKeyPath:@"@avg.floatValue"];
NSNumber *max_f = [array valueForKeyPath:@"@max.floatValue"];
NSNumber *min_f = [array valueForKeyPath:@"@min.floatValue"];
NSLog(@"%@", @[sum_f, avg_f, max_f, min_f]);
打印结果:
[
10,
2,
4,
0
]
4. 排重
数组中相同的只保留一个,排重后的顺序是乱的,不会保留数组之前的顺序
代码如下:
NSArray *array = @[@"aa", @"bb", @"cc", @"aa"];
NSArray *resultArr = [array valueForKeyPath:@"@distinctUnionOfObjects.self"];
NSLog(@"%@", resultArr);
打印:
[
"cc",
"aa",
"bb"
]
5. KeyPath
的嵌套使用
/// 代码
NSArray *array = @[@"aa", @"bb", @"cc", @"aa"];
NSArray *resultArr = [array valueForKeyPath:@"@distinctUnionOfObjects.uppercaseString"];
NSLog(@"%@", resultArr);
/// 打印
[
"AA",
"BB",
"CC"
]
NSArray *array = @[
@{
@"id": @"1",
@"name": @"aa"
},
@{
@"id": @"2",
@"name": @"bb"
},
@{
@"id": @"3",
@"name": @"aa"
},
];
NSArray *resultArr = [array valueForKeyPath:@"@distinctUnionOfObjects.name.uppercaseString"];
NSLog(@"%@", resultArr);
// 打印
[
"AA",
"BB"
]
6. setValue:forKey
和setValue:forKeyPath
setValue:forKey
和setValue:forKeyPath
可以批量设置数组中的元素的值,很意外,数组居然可以用setValue:forKey
和setValue:forKeyPath
,刷新我的认知了,来看看代码
NSArray *array = @[
[@{@"title":@"asdf"} mutableCopy],
[@{@"title":@"asdf"} mutableCopy],
[@{@"title":@"asdf"} mutableCopy]
];
[array setValue:@"哈哈哈哈哈" forKey:@"title"];
NSLog(@"%@", array);
打印结果
[
{
"title" : "哈哈哈哈哈"
},
{
"title" : "哈哈哈哈哈"
},
{
"title" : "哈哈哈哈哈"
}
]
上面代码也可以用setValue:forKeyPath
,如果NSArray
层数比较多的话,就得用setValue:forKeyPath
了
字典和对象的valueForKeyPath
字典和对象的用法是很常用的,不需要过多的叙述
1. 字典可以用连续点的方式取到对应的值,可变字典可以
NSDictionary *dict = @{
@"key1": @{
@"key2": @"哈哈"
}
};
NSLog(@"%@", [dict valueForKeyPath:@"key1.key2"]);
2. 可以通过valueForKeyPath
取对象的值,也可以根据setValue:ForKeyPath
设置对象的值,和KVC一样,就不举例。了
网友评论