Distinct value from core data swift
If you want distinct results, you need to set the fetch request's result type to NSFetchRequestResultType.dictionaryResultType
. You can't fetch managed objects and get distinct results, since there might be more than one managed object with the same value.
That would look something like
let fetchRequest: NSFetchRequest<NSDictionary> = NSFetchRequest(entityName: "Journal")
fetchRequest.propertiesToFetch = ["dateAsNumber"]
fetchRequest.returnsDistinctResults = true
fetchRequest.resultType = .dictionaryResultType
The result will be an array of dictionaries. Each will have one key per entry in propertiesToFetch
(just one in this case).
If you use propertiesToFetch
without dictionaryResultType
, you affect how faulting works but not the contents of the result. Using returnsDistinctResults
only works if you also use propertiesToFetch
, so it's also affected by whether you use dictionaryResultType
.
CoreData get distinct values of Attribute
You should use the backing store to help you get distinct records.
If you want to get an array with just John, Betty, Edward here's how you do it:
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"MyEntity"];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:self.managedObjectContext];
// Required! Unless you set the resultType to NSDictionaryResultType, distinct can't work.
// All objects in the backing store are implicitly distinct, but two dictionaries can be duplicates.
// Since you only want distinct names, only ask for the 'name' property.
fetchRequest.resultType = NSDictionaryResultType;
fetchRequest.propertiesToFetch = [NSArray arrayWithObject:[[entity propertiesByName] objectForKey:@"name"]];
fetchRequest.returnsDistinctResults = YES;
// Now it should yield an NSArray of distinct values in dictionaries.
NSArray *dictionaries = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil];
NSLog (@"names: %@",dictionaries);
How to fetch distinct values in Core Data?
requestedValue is nothing and is obviously not being used (perhaps it was part of some other example that got cut&paste into this example code--who knows). You can just ignore it.
The keys for the dictionary are the same as the attributes you fetched and are defined in your model. So, for example, if you had a person entity with three attributes defined, name, age, phoneNumber, and you requested only name, that would be the only keys with data in your dictionaries. So:
[request setEntity:entity];
[request setResultType:NSDictionaryResultType];
[request setReturnsDistinctResults:YES];
[request setPropertiesToFetch:[NSArray arrayWithObject:@"name"]];
// Execute the fetch
NSError *error;
NSArray *objects = [managedObjectContext executeFetchRequest:request error:&error];
if (objects == nil) {
abort();
}
for( NSDictionary* obj in objects ) {
NSLog(@"Person: %@", [obj objectForKey:@"name"]);
}
// ...
So, if you have 5 people in your data store named Bob, Sally, Joe, Freida and Sue, you would see those names print out. If you want to use any of the other attributes (like their age), you would have to add that to the array you set in setPropertiesToFetch:
.
In most cases, it is probably best to simply retrieve the managed object, however. The object will be faulted so you won't even bring attributes into memory unless you actually access them. Plus, if you want to make changes to the objects, you could and persist them to the store (with managed objects).
Swift Core Data - Request with distinct results
You need to set
request.resultType = NSFetchRequestResultType.DictionaryResultType
It returns dictionaries, but the distinct filter should work.
If you do not want to go down that route, filter in memory (also recommended). Do a normal fetch and then
let distinct = NSSet(array: results.valueForKeyPath("docID") as [String])
With Swift 2.0 I prefer
let distinct = NSSet(array: results.map { $0.docID })
Core Data fetch entities with only unique attributes
You can both propertiesToFetch
and returnsDistinctResults
properties of NSFetchRequest to get distinct result of ages across all entities.
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSFetchRequest_Class/#//apple_ref/occ/instp/NSFetchRequest/propertiesToFetch
let fetchRequest = NSFetchRequest(entityName: "Person")
fetchRequest.resultType = .DictionaryResultType
fetchRequest.propertiesToFetch = ["age"]
fetchRequest.returnsDistinctResults = true
let result = try! managedObjectContext.executeFetchRequest(fetchRequest)
Core Data unique attributes
I've decided to use the validate<key>:error:
method to check if there is already a Managed Object with the specific value of <key>
. An error is raised if this is the case.
For example:
- (BOOL)validateMyAttribute:(id *)value error:(NSError **)error {
// Return NO if there is already an object with a myAtribute of value
}
Thanks to Martin Cote for his input.
Related Topics
Create Spotlight-Like Window in Swift 4
How to Replace Limited Number of Occurrences in String
Ios/Tvos Playground Fails with "Unable to Find Execution Service for Selected Run Destination"
Nsdateformatter Detect 24-Hour Clock in Os X and iOS
How to Create an Uppercase Version of a String in Swiftui
Swift: Overriding Typealias Inside Subclass
From the Swift Repl, How to Get a List of Available Modules
Is Dispatchsemaphore a Good Replacement for Nslock
Swiftui: Navigationlink Not Working If Not in a List
Spritekit Particle Emitter Multi Image
What Does "Constrain to Margins" Mean in Interface Builder in Xcode 6.0.1
How to Rotate an Arkit 4X4 Matrix Around Y Using Apple's Simd Library
Protocol Having Generic Function and Associatedtype
Swift Build Error_If_Any_Output_Files_Are_Specified_They_All_Must_Be
(Appkit) Tab Insertion Inside of Nstextblock