iOS·数据结构选型:在某数据结构中避免重复字符串元素(NSArray,NSSet,NSDictionary)

场景需求:

解析某博客或者书籍网站数据时:已知它的书籍首页URL地址,这个首页含有它的书籍目录及其章节的链接,APP想拉取它的目录节点,然而,该目录页面里面的章节可能有重复的内容,那么解析后,我们向内存中保存章节信息的时候,需要过滤。

过滤的标准:如果某数据结构中含有重复的url,就不再重复保存。

数据结构选型:

  • 数组:查询复杂度O(N)
    • NSArray
  • 哈希表:查询复杂度O(1)
    • NSSet
    • NSDictionary

1. 数组方案

1.1 原生containsObject:方案

  • 过滤引擎
- (NSString *)fileterUrl{
  //...
  if ([self.sectionUrlArr containsObject:sectionUrlStr]) {
        return nil;
  }
  [self.sectionUrlArr addObject:sectionUrlSt];
  //...
  • 解析引擎
sectionUrlStr = [FilterEngine filterUrl];
if (sectionModel.sectionUrlStr) {
   [sectionArr addObject:sectionModel];
}
  • 实验结果

过滤成功。

1.2 自定义类改写isEqual方案

数组的containsObject:只能检测 内存地址相同 的对象,并不能检测 内存不同但字符串内容相 的NSString对象。

  • 自定义EqualString.m
#import "EqualString.h"

@implementation EqualString

- (BOOL)isEqual:(id)object {
    if (self == object) {
        return YES;
    }
    
    if (![object isKindOfClass:[NSString class]]) {
        return NO;
    }
    
    NSString *strEntity = (NSString *)object;
    
    if ([strEntity isEqualToString:self]) {
        return YES;
    } else {
        return NO;
    }
}

@end
  • 实验结果

过滤成功。

1.3 分类改写isEqual方案

除了自定义NSSting类,再考察使用分类NSString+Equal重写isEqual的方案。

  • 分类NSString+Equal.m
#import "NSString+Equal.h"

@implementation NSString (Equal)

- (BOOL)isEqual:(id)object {
    if (self == object) {
        return YES;
    }
    
    if (![object isKindOfClass:[NSString class]]) {
        return NO;
    }
    
    NSString *strEntity = (NSString *)object;
    
    if ([strEntity isEqualToString:self]) {
        return YES;
    } else {
        return NO;
    }
}

@end
  • 实验结果

这种方案最后无效。

  • 缺点

除了方案不成功,另外很怪异的是,这样写分类并拖到到工程,会对全局的NSString都有影响。即使没有任何地方import该分类。

2. 哈希表结构

其实,对于上述的数组类型的数据结构,如果要查询一个元素,时间复杂度是比较高的,因为它必须遍历才能实现查询操作。

而实际应用中,查询效率比较高的是哈希表,这种结构在OC开发中有两种常见形式,一种是字典,一种是集合。集合每个元素只需要一样值即可,而字典每个元素则需要存储两种数据,键和值。

哈希表

另外,哈希结构在Android开发中对应的形式则类似下面的:

private static HashSet<String> sectionUrlSet = new HashSet<>();

2.1 NSSet方案

  • 代码
- (NSMutableSet *)sectionUrlSet {
    if(!_sectionUrlSet){
        _sectionUrlSet = [NSMutableSet set];
    }
    return _sectionUrlSet;
}
  • 解析引擎
if ([self.sectionUrlSet containsObject:sectionUrlStr]) {
    return nil;
}
[self.sectionUrlSet addObject:sectionUrlStr];
  • 实验结果

过滤成功。

2.2 NSDictionary方案

  • 实验代码
- (NSMutableSet *)sectionUrlDict {
    if(!_sectionUrlDict){
        _sectionUrlDict = [NSMutableDictionary dictionary];
    }
    return _sectionUrlDict;
}
  • 解析引擎
if ([[self.sectionUrlDict allKeys] containsObject:sectionUrlStr]) {
    return nil;
}
[self.sectionUrlDict setObject:@"" forKey:sectionUrlStr];
  • 实验结果

过滤成功。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序生活

Python pickle的使用pickle简介实例参考资料

pickle模块是对Python对象结构进行二进制序列化和反序列化的协议实现,就是把Python数据变成流的形式。

9110
来自专栏進无尽的文章

RunTime 之其他实践运用

有关Runtime的知识总结,我本来想集中写成一篇文章的,但是最后发现实在是太长,而且不利于阅读,最后分成了如下几篇:

11830
来自专栏Java学习网

Java Web Response对象的27个方法及状态码

response表示HttpServletResponse对象,主要将JSP容器处理后的结果传回到客户端。 ? 网络配图 1、void addCookie(...

54270
来自专栏進无尽的文章

编码篇-ARC下的内存泄漏

内存泄露是一个相对挺严重的问题,可是它的存在未引起足够的重视,如果程序运行时一直分配内存而不及时释放无用的内存,程序占用的内存越来越大,直到把系统分配给该APP...

15420
来自专栏我有一个梦想

QT Creator 快速入门教程 读书笔记(三)

一   信号和槽   GUI 程序除了要绘制控件,还要响应系统和用户事件,例如重绘、绘制完成、点击鼠标、敲击键盘等。当事件发生时,UI 会产生相应的变化,让用户...

30280
来自专栏陈满iOS

iOS·子父类同时实现KVO响应方法时的执行顺序

18810
来自专栏学海无涯

iOS开发之通过代理逆向传值

在iOS开发中,传值是几乎每个App都会用到的,对于传统的顺向传值应该说是比较简单的,但是逆向传值往往会用到代理模式来实现,很多同学在这一块有迷惑,迷惑的不是怎...

29050
来自专栏冰霜之地

iOS如何优雅的处理“回调地狱Callback hell”(一)——使用PromiseKit

最近看了一些Swift关于封装异步操作过程的文章,比如RxSwift,RAC等等,因为回调地狱我自己也写过,很有感触,于是就翻出了Promise来研究学习一下。...

55130
来自专栏陈满iOS

iOS·NSObject的两种含义:类与协议

iOS开发中,苹果提供的一些系统类都属于NSObject的子类,例如UIColor类的定义如下所示。

17650
来自专栏编程之旅

iOS开发——自主设计日志系统

好像很久没有写有关iOS的文章了,其实iOS的开发一直都是在进行的,但是最近有需求拓宽知识的宽度,所以一直在接触别的知识,当然啦,移动端开发并不能丢下。

18120

扫码关注云+社区

领取腾讯云代金券