Reputation: 7922
I"m performing a regular NSFetchRequest
without any predicate to fetch 100 managed objects (flights), each Flight
entity has an attribute of type NSString
named (flightCode) and this attribute is not unique, so 2 flight objects may have the same flightCode .
However, I want to fetch all flight objects filtering out flights that have the same flightCode by taking only one flight from similarities, i.e.
if the fetch request returned 5 flights as follows:
flight1: flightCode = ABC
flight2: flightCode = AA
flight3: flightCode = ABC
flight4: flightCode = ABC
flight5: flightCode = DEF
then the fetch request must filter out any two of the 3 flights that have the flightCode ABC
and take only any random one of these 3.
what is the required NSPredicate
for this filtering ?
p.s. flights: 1, 3 & 4 may be different in other attributes, i.e. flight1's name may be different from flight3's name.
thanks in advance.
Upvotes: 1
Views: 135
Reputation: 385590
If you just want a list of all distinct flight codes, this may do what you want:
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Flight"
inManagedObjectContext:moc];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entity.name];
request.resultType = NSDictionaryResultType;
request.returnsDistinctResults = YES;
request.propertiesToFetch = @[ entity.propertiesByName[@"flightCode"] ];
Note that returnsDistinctResults
only works if propertiesToFetch
is set, and propertiesToFetch
only works if resultType
is NSDictionaryResultType
.
If you want full Flight
objects, but only one for each distinct flight code, I don't think you can do that directly. Perhaps you can ask for both the object ID and the flight code, group by flight code, and take the minimum object ID, to get one object ID for each flight code. Then you can turn those object IDs into full objects one by one using objectForID:
on the managed object context. I would try something like this:
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Flight"
inManagedObjectContext:moc];
NSExpressionDescription *objectIDProperty = [[NSExpressionDescription alloc] init];
objectIDProperty.name = @"objectID";
objectIDProperty.expression = [NSExpression expressionForFunction:@"min:"
arguments:@[ [NSExpression expressedForEvaluatedObject] ]];
objectIdProperty.expressionResultType = NSObjectIDAttributeType;
NSAttributeDescription *flightCodeProperty = entity.propertiesByName[@"flightCode"];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entity.name];
request.resultType = NSDictionaryResultType;
request.returnsDistinctResults = YES;
request.propertiesToFetch = @[ flightCodeProperty, objectIDProperty ];
request.propertiesToGroupBy = @[ flightCodeProperty ];
I cribbed a lot of that from this answer. I have no idea if it works, or if I'm even on the right track. If it runs at all, but doesn't quite give the right output, remember that you can see the SQL it's executing by adding -com.apple.CoreData.SQLDebug 1
as a command-line argument.
Upvotes: 1
Reputation: 607
youll want to make a NSMuteableArray
for all of your flights and then a separate NSMuteableArray
to keep track of which elements you have already seen
pseudocode:
NSMuteablearray flights
NSMuteablearray alreadySeen
for (item in flights) {
if (alreadySeen containsObject:item)
flights removeObject:item
else
alreadySeen addObject:item
}
Upvotes: 0