Ios 枚举数组以查找另一个数组中的项的有效方法
在不无意中破坏性能的情况下,乍一看,一个列表中可能有200个guid字符串与另一个列表中的100个guid字符串相等,以找到匹配的索引,这是否是可以接受的 我有一个这样定义的方法签名Ios 枚举数组以查找另一个数组中的项的有效方法,ios,objective-c,arrays,Ios,Objective C,Arrays,在不无意中破坏性能的情况下,乍一看,一个列表中可能有200个guid字符串与另一个列表中的100个guid字符串相等,以找到匹配的索引,这是否是可以接受的 我有一个这样定义的方法签名 -(NSArray*)getItemsWithGuids:(NSArray*)guids 我想把它放在guid数组中,并与这个数组一起使用 NSArray *allPossibleItems; // Has objects with a property named guid. 。。。从guids 我的第一反应
-(NSArray*)getItemsWithGuids:(NSArray*)guids
我想把它放在guid
数组中,并与这个数组一起使用
NSArray *allPossibleItems; // Has objects with a property named guid.
。。。从guids
我的第一反应是尝试indexesOfObjectsPassingTest
,但在组合块之后,我想知道iOS框架是否已经提供了更有效地进行此类比较的功能
-(NSArray*)getItemsWithGuids:(NSArray*)guids
{
NSIndexSet *guidIndexes = [allPossibleItems indexesOfObjectsPassingTest:^BOOL(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop)
{
SomeObjWithGuidProperty *someObject = obj;
for (NSString *guid in guids) {
if ([someObject.guid isEqualToString:guid]) {
return YES;
}
}
return NO;
}];
if (guidIndexes) {
// Have more fun here.
}
}
由于您使用的是Objective-C(不是Swift),请检查。在您的情况下,您可以执行以下操作:
guids.find(^(NSString *guid){
return [someObject.guid isEqualToString:guid];
});
由于您使用的是Objective-C(不是Swift),请检查。在您的情况下,您可以执行以下操作:
guids.find(^(NSString *guid){
return [someObject.guid isEqualToString:guid];
});
我的想法是使用一套-
-(NSArray*)getItemsWithGuids:(NSArray*)guids inAllObjects:(NSArray *)allObjects
{
NSSet *matchGuids=[NSSet setWithArray:guids];
NSMutableArray *matchingObjects=[NSMutableArray new];
for (SOmeObjectWithGuidProperty *someObject in allObjects) {
if ([matchGuids contains:someObject.guid]) {
[matchingObjects addObject:someObject];
}
}
return [matchingObjects copy];
}
我的想法是使用一套-
-(NSArray*)getItemsWithGuids:(NSArray*)guids inAllObjects:(NSArray *)allObjects
{
NSSet *matchGuids=[NSSet setWithArray:guids];
NSMutableArray *matchingObjects=[NSMutableArray new];
for (SOmeObjectWithGuidProperty *someObject in allObjects) {
if ([matchGuids contains:someObject.guid]) {
[matchingObjects addObject:someObject];
}
}
return [matchingObjects copy];
}
您的代码看起来会有O(n^2)性能,这是很糟糕的。我认为将guid转换为
NSSet
然后使用NSSet
的containsObject
的解决方案可能会更有效。您可以很容易地重写对象分配测试的索引,以使用NSSet
和containsObject
。您的代码看起来会有O(n^2)性能,这是很糟糕的。我认为将guid转换为NSSet
然后使用NSSet
的containsObject
的解决方案可能会更有效。您可以很容易地重写对象分配测试的索引,以使用NSSet
和containsObject
。如果顺序不太重要,我建议在这里更改数据结构。而不是使用<代码> NSArray < /代码>,考虑使用<代码> nSc字典< /C> >以代码> GUID <代码>为关键字,<代码>某个对象< /代码>为值。在这种情况下,您应该使用-[NSDictionary objectsForKeys:notFoundMarker:][/code>方法来获取对象
它的工作速度比2个数组快得多。如果NSDictionary
键具有良好的哈希函数,则访问元素、设置元素和删除元素都需要固定的时间NSString
具有良好的哈希
-(NSArray*)getItemsWithGuids:(NSArray*)guids {
NSArray *objectsAndNulls = [allPossibleItemsDictionary objectsForKeys:guids notFoundMarker:[NSNull null]];
if (objectsAndNulls) {
// Have more fun here.
// You should check that object in objectsAndNulls is not NSNull before using it
}
return objectsAndNulls;
}
UPD不幸的是,无法将nil
作为notFoundMarker传递。如果无法提供可用的notFoundMarker值,并且不想执行其他检查,则可以逐个查询对象并填充NSMutableArray
。在这种情况下,您将避免通过数组删除NSNull
s:
-(NSArray*)getItemsWithGuids:(NSArray*)guids {
NSMutableArray *objects = [NSMutableArray arrayWithCapacity:guids.count];
for (NSString *guid in guids) {
SomeObjWithGuidProperty *object = allPossibleItemsDictionary[guid];
if (nil != object) {
[objects addObject:object];
}
}
if (nil != objects) {
// Have more fun here.
}
return object;
}
如果顺序不太重要,我建议在这里更改数据结构。而不是使用<代码> NSArray < /代码>,考虑使用<代码> nSc字典< /C> >以代码> GUID <代码>为关键字,<代码>某个对象< /代码>为值。在这种情况下,您应该使用-[NSDictionary objectsForKeys:notFoundMarker:][/code>方法来获取对象
它的工作速度比2个数组快得多。如果NSDictionary
键具有良好的哈希函数,则访问元素、设置元素和删除元素都需要固定的时间NSString
具有良好的哈希
-(NSArray*)getItemsWithGuids:(NSArray*)guids {
NSArray *objectsAndNulls = [allPossibleItemsDictionary objectsForKeys:guids notFoundMarker:[NSNull null]];
if (objectsAndNulls) {
// Have more fun here.
// You should check that object in objectsAndNulls is not NSNull before using it
}
return objectsAndNulls;
}
UPD不幸的是,无法将nil
作为notFoundMarker传递。如果无法提供可用的notFoundMarker值,并且不想执行其他检查,则可以逐个查询对象并填充NSMutableArray
。在这种情况下,您将避免通过数组删除NSNull
s:
-(NSArray*)getItemsWithGuids:(NSArray*)guids {
NSMutableArray *objects = [NSMutableArray arrayWithCapacity:guids.count];
for (NSString *guid in guids) {
SomeObjWithGuidProperty *object = allPossibleItemsDictionary[guid];
if (nil != object) {
[objects addObject:object];
}
}
if (nil != objects) {
// Have more fun here.
}
return object;
}
在if
语句中,不要将*stop
设置为YES
。这样做意味着guidIndexes
最多只能包含一个索引。为什么getItemsWithGuids:forGuids:
方法的返回类型设置为NSArray*
,但返回的是NSIndexSet
?请检查此线程,比较不同的方法@如果这让人困惑,我很抱歉。我将使用在搜索中找到的guidIndexes
返回在allPossibleItems
数组中找到的匹配对象数组。“guid”听起来像是一个很好的NSDictionary键。甚至超出此问题范围的更好设计可能是将具有guid属性的对象保留在索引数据结构中,如NSDictionaryDon't set*stop
到YES
在if
语句中。这样做意味着guidIndexes
最多只能包含一个索引。为什么getItemsWithGuids:forGuids:
方法的返回类型设置为NSArray*
,但返回的是NSIndexSet
?请检查此线程,比较不同的方法@如果这让人困惑,我很抱歉。我将使用在搜索中找到的guidIndexes
返回在allPossibleItems
数组中找到的匹配对象数组。“guid”听起来像是一个很好的NSDictionary键。甚至超出此问题范围的更好设计可能是将具有guid属性的对象保留在索引数据结构中,如NSDictionaryallGuids
应该是:NSSet*allGuids=[NSSet setWithArray:guids]代码>。而
的循环应该在allObjects
上。你为什么这么说?我更改了函数签名,因为在原来的问题中,allPossibleItems
不知从何而来,尽管输入参数名为guids
,但它实际上似乎在OP的代码中包含SomeObjWithGuidProperty
的实例,guids
是一个由NSString
组成的数组,allObjects
是一个由SomeObjWithGuidProperty组成的数组