ios CoreData 获取不同的属性值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7000768/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:01:41  来源:igfitidea点击:

CoreData get distinct values of Attribute

ioscore-datansfetchrequest

提问by ephilip

I'm trying to setup my NSFetchRequestto core data to retrieve the unique values for a specific attribute in an entity. i.e.

我正在尝试设置我NSFetchRequest的核心数据以检索实体中特定属性的唯一值。IE

an entity with the following information:

具有以下信息的实体:

  name | rate | factor |
_______|______|________|
John   |  3.2 |    4   |
Betty  |  5.5 |    7   |
Betty  |  2.1 |    2   |
Betty  |  3.1 |    2   |
Edward |  4.5 |    5   |
John   |  2.3 |    4   |

How would i set up the request to return an array with just: John, Betty, Edward?

我将如何设置仅返回数组的请求:John、Betty、Edward?

回答by AlleyGator

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:

如果你想得到一个只有 John、Betty、Edward 的数组,你可以这样做:

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);

回答by TechZen

You're trying to use Core Data like a procedural data base instead of as an object graph manager as the API intended, so you won't find an easy way to do this.

您正在尝试将 Core Data 用作过程数据库,而不是像 API 预期的那样用作对象图管理器,因此您找不到一种简单的方法来执行此操作。

There isn't a straight forward way to do this in Core Data because Core Data is concerned with objects instead of values. Since managed objects are guaranteed to be unique, Core Data doesn't much care about each object's values or whether they are duplicates or some other object's values.

在 Core Data 中没有直接的方法来做到这一点,因为 Core Data 关注的是对象而不是值。由于托管对象保证是唯一的,Core Data 不太关心每个对象的值,或者它们是重复的还是其他对象的值。

To find the unique values:

要查找唯一值:

  1. Perform a fetch by specific value. That will give you an array of dictionaries with a key nameand a value of the name string itself.
  2. On the returned array in (1) use a set collection operatorto return a set of unique values.
  1. 按特定值执行提取。这将为您提供一个字典数组,其中包含一个键name和名称字符串本身的值。
  2. 在 (1) 中返回的数组上,使用集合运算符返回一组唯一值。

So, something like:

所以,像这样:

NSSet *uniqueNames=[fetchedNameDicts valueForKeyPath:@"@distinctUnionOfSets.name"];

... which will return a set of NSString objects all with a unique value.

...这将返回一组具有唯一值的 NSString 对象。

回答by Alexandre L Telles

Give a look at Fetching Specific Property Values, it's not necessary to use a Set to get distinct values.

看看Fetching Specific Property Values,没有必要使用 Set 来获取不同的值。

回答by Johannes Fahrenkrug

This is a simple approach in Swift 5.x:

这是 Swift 5.x 中的一个简单方法:

// 1. Set the column name you want distinct values for
let column = "name"

// 2. Get the NSManagedObjectContext, for example:
let moc = persistentContainer.viewContext

// 3. Create the request for your entity
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "User")

// 4. Use the only result type allowed for getting distinct values
request.resultType = .dictionaryResultType

// 5. Set that you want distinct results
request.returnsDistinctResults = true

// 6. Set the column you want to fetch
request.propertiesToFetch = [column]

// 7. Execute the request. You'll get an array of dictionaries with the column
// as the name and the distinct value as the value
if let res = try? moc.fetch(request) as? [[String: String]] {
    print("res: \(res)")

    // 8. Extract the distinct values
    let distinctValues = res.compactMap { ##代码##[column] }
}