美文网首页iOS基础
valueForKey详解

valueForKey详解

作者: 庞仕山 | 来源:发表于2018-11-20 13:45 被阅读22次

    今天看一个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:forKeysetValue:forKeyPath

    setValue:forKeysetValue:forKeyPath可以批量设置数组中的元素的值,很意外,数组居然可以用setValue:forKeysetValue: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一样,就不举例。了

    如果觉得有帮助, 点个star吧

    相关文章

      网友评论

        本文标题:valueForKey详解

        本文链接:https://www.haomeiwen.com/subject/zhitzttx.html