问题
I have 2 NSMutableArrays that contains an instances of the class Person. I need to check is there any Person with same value of "name" in both of arrays and merge it with ask about replace instances of Reson with same value "name".
It looks like:
empl1 = [
Person [
name = @"Paul",
age = 45,
],
Person [
name = @"John",
age = 36,
]
]
empl2 = [
Person [
name = @"Paul",
age = 47,
],
Person [
name = @"Sean",
age = 30,
]
]
Then program ask about replacement Person @"Paul" in empl1 with Person @"Paul" in empl2 and add any new persons from empl2 to empl2
And result must be (if we replace Paul):
empl = [
Person [
name = @"Paul",
age = 47,
],
Person [
name = @"John",
age = 36,
],
Person [
name = @"Sean",
age = 30,
]
]
Think about this 2 days but without success. Please help :)
回答1:
you could implement -isEqual:
and hash
on Person and put all objects in a Set.
@interface Person : NSObject
@property(copy) NSString *name;
@property NSUInteger age;
@end
@implementation Person
-(BOOL)isEqual:(id)otherPerson
{
if([otherPerson isKindOfClass:[self class]])
return [self.name isEqual:otherPerson.name];
return false;
}
-(NSUInteger)hash
{
return [self.name hash];
}
@end
if you now put it into an NSSet or NSOrderedSet just the first object with the same name will be kept. The other will be detected as duplicate and not stored in the set.
For more: Collections Programming Topics
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property(copy) NSString *name;
@property NSUInteger age;
-(id)initWithName:(NSString *)name age:(NSUInteger)age;
@end
@implementation Person
-(id)initWithName:(NSString *)name age:(NSUInteger)age
{
if(self = [super init])
{
_name = name;
_age = age;
}
return self;
}
-(BOOL)isEqual:(id)otherPerson
{
if([otherPerson isKindOfClass:[self class]]){
Person *rhsPerson = otherPerson;
return [self.name isEqualToString:rhsPerson.name];
}
return false;
}
-(NSUInteger)hash
{
return [self.name hash];
}
-(NSString *)description
{
return [NSString stringWithFormat:@"%@ %lu", self.name, self.age];
}
@end
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSArray *p1Array = @[[[Person alloc] initWithName:@"Paul" age:45] ,
[[Person alloc] initWithName:@"John" age:36]];
NSArray *p2Array = @[[[Person alloc] initWithName:@"Paul" age:47] ,
[[Person alloc] initWithName:@"Sean" age:30]];
NSMutableSet *resultSet = [[NSMutableSet alloc] initWithArray:p1Array];
NSMutableSet *duplicates = [[NSMutableSet alloc] initWithArray:p2Array];
[duplicates intersectSet:resultSet];
[resultSet addObjectsFromArray:p2Array];
if ([duplicates count]) {
for (Person *p in [duplicates allObjects]) {
NSMutableSet *interSet = [resultSet mutableCopy];
[interSet intersectSet:[NSSet setWithObject:p]];
Person *pInSet = [interSet allObjects][0];
NSLog(@"%@ <-> %@", p, pInSet);
/*
Here you have the pairs of duplicated objects.
depending on your further requierements, stror them somewhere
and process it further after asking the user.
*/
}
}
}
return 0;
}
回答2:
You should definitely use NSSet.
Here's an example:
NSMutableArray *temp1 = @[@1, @2, @3];
NSMutableArray *temp2 = @[@4, @1, @5];
NSMutableSet *set1 = [NSMutableSet setWithArray:temp1];
NSMutableSet *set2 = [NSMutableSet setWithArray:temp2];
[set1 unionSet:set2];
Here's the documentation. And here's the documentation of mutable version of NSSet.
来源:https://stackoverflow.com/questions/16095424/how-to-compare-and-merge-nsmutablearray