I have an NSMutableArray
which has entity class object as its objects.
Now I want to remove the distinct objects from it. Consider following example
Entity *entity = [[Entity alloc] init];
entity.iUserId = 1;
entity.iUserName = @"Giri"
[arr addObject:entity];
Entity *entity = [[Entity alloc] init];
entity.iUserId = 2;
entity.iUserName = @"Sunil"
[arr addObject:entity];
Entity *entity = [[Entity alloc] init];
entity.iUserId = 3;
entity.iUserName = @"Giri"
[arr addObject:entity];
Now I want only two objects in the Array
by removing the duplicate iUserName. I know the way by iteration but I want it without iterating it like predicate
or some other way.
If anyone knows then please help me.
I had tried using [arr valueForKeyPath:@"distinctUnionOfObjects.iUsername"];
but it does not return me the entired object.
This question is totally different than the questions which are asked previously. Previously asked question is for getting the distinct objects is correct but they uses looping & I don't want this. I want it from NSPredicate
or any other simple option which avoids looping.
EDIT: You can't do what you want to without looping over the array manually and building up a new array. The answer below won't work because it assumes that there are only at most two duplicates.
NSMutableArray *filteredArray = [NSMutableArray array];
for (Entity *entity in arr)
{
BOOL hasDuplicate = [[filteredArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"iUserName == %@", entity.iUserName]] count] > 0;
if (!hasDuplicate)
{
[filteredArray addObject:entity];
}
}
This will look for duplicates in the filtered array as it builds it.
Begin Original Answer
You can't use an NSSet
because the Entity
instances would have to return NSOrderedSame
in compareTo:
, which isn't a good idea since you shouldn't use names as unique identifiers.
You can use predicates, but they'll still loop over the array in an O(n^2)
time without some optimization.
NSArray *filteredArray = [arr filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(Entity *evaluatedObject, NSDictionary *bindings) {
return [[arr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"iUserName == %@", evaluatedObject.iUserName]] count] > 1;
}]];
That'll work fine. You could make it even faster by sorting the array by the iUserName
property first and doing a linear scan over the sorted array (stopping when you see the first duplicate). That's a lot of work if you're dealing with small sample sizes (say, under ten thousand or so). It's probably not worth your time, so just use the code above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With