Objective-C:如何选择性合并两个数组?
Got it, since you’re already comfortable with basic NSArray concatenation, let’s dive straight into solving your incremental update scenario for NoteTemplate objects. The core challenge here isn’t just stitching two arrays together—it’s merging them while ensuring you keep the latest versions of each object and avoid duplicates.
First, let’s assume your NoteTemplate class has two critical properties for this task:
- A unique identifier (e.g.,
templateIdof typeNSString*) - An update timestamp (e.g.,
lastUpdatedAtof typeNSDate*)
These are essential for determining which version of an object is the most recent. Here are two efficient approaches tailored to your use case:
Approach 1: Dictionary-Based Merging (Best for Large Datasets)
This method leverages a dictionary for O(1) lookups, making it far more efficient than array traversals when dealing with large numbers of objects.
- Convert your local cached array into a mutable dictionary, keyed by the unique
templateId:
NSMutableDictionary *localTemplateMap = [NSMutableDictionary dictionary]; for (NoteTemplate *template in yourLocalCachedArray) { localTemplateMap[template.templateId] = template; }
- Iterate through your incremental update array and update the dictionary:
for (NoteTemplate *updatedTemplate in yourIncrementalUpdateArray) { NoteTemplate *existingTemplate = localTemplateMap[updatedTemplate.templateId]; // Either replace directly (if you trust the server always sends the latest) // or compare timestamps to ensure we only keep the newer version if (!existingTemplate || [updatedTemplate.lastUpdatedAt compare:existingTemplate.lastUpdatedAt] == NSOrderedDescending) { localTemplateMap[updatedTemplate.templateId] = updatedTemplate; } }
- Convert the dictionary back to a final array (you can sort it if needed):
NSArray *finalMergedArray = [localTemplateMap allValues]; // Optional: Sort by update time or original order finalMergedArray = [finalMergedArray sortedArrayUsingComparator:^NSComparisonResult(NoteTemplate *a, NoteTemplate *b) { return [a.lastUpdatedAt compare:b.lastUpdatedAt]; }];
Approach 2: Preserving Original Local Order
If you need to maintain the original order of your local cached array while inserting/updating new objects, use this approach:
- Create a mutable copy of your local array and a set of existing IDs for quick checks:
NSMutableArray *finalMergedArray = [yourLocalCachedArray mutableCopy]; NSMutableSet *existingTemplateIds = [NSMutableSet setWithArray:[yourLocalCachedArray valueForKey:@"templateId"]];
- Process each object in the incremental update array:
for (NoteTemplate *updatedTemplate in yourIncrementalUpdateArray) { if ([existingTemplateIds containsObject:updatedTemplate.templateId]) { // Replace the existing object with the updated version NSUInteger index = [finalMergedArray indexOfObjectPassingTest:^BOOL(NoteTemplate *obj, NSUInteger idx, BOOL *stop) { return [obj.templateId isEqualToString:updatedTemplate.templateId]; }]; if (index != NSNotFound) { finalMergedArray[index] = updatedTemplate; } } else { // Add new objects (you can choose where to insert—here we append to the end) [finalMergedArray addObject:updatedTemplate]; [existingTemplateIds addObject:updatedTemplate.templateId]; } }
Key Notes to Remember
- Immutable vs. Mutable Objects: If
NoteTemplateis an immutable class, replacing objects in the array/dictionary is safe. If it’s mutable, make sure to create deep copies when updating to avoid accidentally modifying your original cached objects. - Server Trust: If your web service guarantees that incremental updates always contain the latest version of an object, you can skip the timestamp comparison step for simplicity.
- Performance: The dictionary approach is significantly faster for large datasets (O(n) time complexity vs. O(n²) for repeated array lookups).
内容的提问来源于stack exchange,提问作者mbm29414

