程序员你好 苹果iOS

ios 数组遍历问题

2022-12-07  本文已影响0人  笨驴爱吃胡萝卜

起因

经常处理数据的时候 会遇到这样的问题。
看到其他语言如swift 或者python 都有自己的map filter 的语法,OC却要用for 语句
1.网络请求的数据,需要数组中第几个元素进行计算
2.需要满足部分的元素形成一个新的数组
一般关于这两个问题的反映是用for 数组 ,然后new 一个新的可变数组把符合条件的数据加入到数组中

NSMutableArray *marr = [NSMutableArray array];
for (int i = 0 ; i < array.count; i++) {
        id temp = array[i];
         if(temp 满足条件) {
            [marr addobject:temp]; 
            这个时候 得到了一个满足条件的数组
          }
}

简单的还好,如果涉及很多需要满足条件的计算 ,这样的代码可读性和维护性,都非常的有挑战。

方案一

把for 的语句封装起来

方案二

添加NSArray的Category
*.h 文件


#import <Foundation/Foundation.h>

typedef BOOL(^filterCondition)(id target);
typedef id  (^mapCondition)(id target);

@interface NSArray (Common)

- (NSArray *)reverse;

/// 筛选出所有符合条件的元素
/// @param condition 筛选条件
- (NSArray *)filter:(filterCondition)condition;

/// 筛选出前几个符合条件的元素
/// @param condition 筛选条件
/// @param count 需要的数量
- (NSArray *)filter:(filterCondition)condition theTopServeral:(NSUInteger)count;

/// 筛选出后几个符合条件的元素
/// @param condition 筛选条件
/// @param count 需要的数量
- (NSArray *)filter:(filterCondition)condition theEndServeral:(NSUInteger)count;

/// map遍历
- (NSArray *)map:(mapCondition)condition;
 
@end

*.m 文件


#import "NSArray+Common.h"

@implementation NSArray (Common)

- (NSArray *)reverse {
    return [[[NSMutableArray arrayWithArray:self] reverseObjectEnumerator] allObjects];
}

- (NSArray *)filter:(filterCondition)condition {
    return [self filter:condition needCount:self.count isTopSeveral:YES];
}

- (NSArray *)filter:(filterCondition)condition theTopServeral:(NSUInteger)count {
    return [self filter:condition needCount:count isTopSeveral:YES];
}

- (NSArray *)filter:(filterCondition)condition theEndServeral:(NSUInteger)count {
    return [self filter:condition needCount:count isTopSeveral:NO];
}

- (NSArray *)filter:(filterCondition)condition needCount:(NSUInteger)count isTopSeveral:(BOOL)isTopSeveral {
    if (count < 1) {
        return @[];
    }
    
    NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:self.count];
    [self enumerateObjectsWithOptions:isTopSeveral ? NSEnumerationConcurrent : NSEnumerationReverse usingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (tmp.count >= count - 1) {
            *stop = YES;
        }
        if (condition(obj)) {
            [tmp addObject:obj];
        }
    }];
    return tmp.copy;
}

- (NSArray *)map:(mapCondition)condition {
    if (!self.count) {
        return self;
    }
    
    NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:self.count];
    [self enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (condition(obj)) {
            [tmp addObject:condition(obj)];
        } else {
            #ifdef DEBUG
            NSString *tipString = [NSString stringWithFormat:@"元素不符合遍历条件,index = %ld, 元素:%@", idx, obj];
            NSAssert(NO, tipString);
            #endif
        }
    }];
    return tmp.copy;
}

@end

代码的核心 一句 就是enumerateObjectsUsingBlock

使用方法

这里的target 是id 类型,可以是网络请求下来的model ,也可以是字符串 int 等类型

直接返回 float

NSArray *arr = @[@"asd",@"bcd3",@"aew",@"zxc",@"123",@"567",@"bnj",@"opi",@"tytreu",@"qwerty",@"12"];
NSArray *sortArray = [arr filter:^BOOL(NSString * target) {
      return target.length > 2;
}];
NSLog(@"print array - %@",sortArray);
NSArray *topSerArr =  [arr filter:^BOOL(NSString * target) { 
      return target.length > 2;
  } theTopServeral:4];
NSLog(@"print tio serveral array - %@",topSerArr);

通过block 的内部条件进行数据筛选,把筛选条件明确的展示在最显眼的位置

总结

这个优化虽然和小,但是一个大型项目恰恰是每一处的优化才带来整体的效率提升。

上一篇下一篇

猜你喜欢

热点阅读