今天看一個K線的庫,看到了用數組的
valueForKeyPath求數組中某個字段的平均值,沒有用到for循環(huán),之前我是沒這樣用過的,于是決定研究一下這個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);
打?。?/strong>
[
"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. 字典可以用連續(xù)點的方式取到對應的值,可變字典可以
NSDictionary *dict = @{
@"key1": @{
@"key2": @"哈哈"
}
};
NSLog(@"%@", [dict valueForKeyPath:@"key1.key2"]);
2. 可以通過valueForKeyPath取對象的值,也可以根據setValue:ForKeyPath設置對象的值,和KVC一樣,就不舉例。了