Ios 如何计算CoreData对象的唯一日期?
我需要一种正确的方法来计算具有NSDate类型属性的CoreData对象中有多少唯一的天数 例如,我有以下几点:Ios 如何计算CoreData对象的唯一日期?,ios,core-data,count,nsdate,nsmanagedobject,Ios,Core Data,Count,Nsdate,Nsmanagedobject,我需要一种正确的方法来计算具有NSDate类型属性的CoreData对象中有多少唯一的天数 例如,我有以下几点: <Object>.date = "2014-05-15 21:29:12 +0000"; <Object>.date = "2014-05-15 21:49:34 +0000"; <Object>.date = "2014-05-16 13:29:23 +0000"; <Object>.date = "2014-05-16 20:49:
<Object>.date = "2014-05-15 21:29:12 +0000";
<Object>.date = "2014-05-15 21:49:34 +0000";
<Object>.date = "2014-05-16 13:29:23 +0000";
<Object>.date = "2014-05-16 20:49:50 +0000";
<Object>.date = "2014-05-16 22:01:53 +0000";
<Object>.date = "2014-05-20 03:32:12 +0000";
<Object>.date = "2014-05-20 12:45:23 +0000";
<Object>.date = "2014-05-20 14:15:50 +0000";
<Object>.date = "2014-05-20 20:20:05 +0000";
.date=“2014-05-15 21:29:12+0000”;
.date=“2014-05-15 21:49:34+0000”;
.date=“2014-05-16 13:29:23+0000”;
.date=“2014-05-16 20:49:50+0000”;
.date=“2014-05-16 22:01:53+0000”;
.date=“2014-05-20 03:32:12+0000”;
.date=“2014-05-20 12:45:23+0000”;
.date=“2014-05-20 14:15:50+0000”;
.date=“2014-05-20:20:05+0000”;
在这种情况下,结果必须是3,因为有3个不同的日期,2014-05-15、2014-05-16和2014-05-20
有办法解决这个问题吗?
我尝试了NSPredicate,但没有成功
谢谢 那很容易。让我告诉你我要为它做什么 使用排序描述码对结果进行分组。此示例帮助您了解如何实现它 然后计算这些组 编辑: NSDate+Utils.h
- (NSDate *) dateWithoutTime
NSDate+Utils.m
-(NSDate *) dateWithoutTime
{
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:self];
return [calendar dateFromComponents:components];
}
一些文件
- (NSUInteger) someObjectsCount
{
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"SomeObject"];
NSString *key = @"date.dateWithoutTime";
fetchRequest.sortDescriptors = @[[[NSSortDescriptor alloc] initWithKey:key
ascending:YES]];
NSManagedObjectContext *context;
context = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSFetchedResultsController *aFetchedResultsController;
aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:context
sectionNameKeyPath:key
cacheName:nil];
[aFetchedResultsController performFetch:nil];
return [[aFetchedResultsController sections] count];
}
就这些 您应该有一个名为“daydate”的新属性,该属性是从当前日期和时间设置为午夜的日期 每次创建/修改其中一个对象时,操作如下:
NSDate *date = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
[calendar setTimeZone:[NSTimeZone systemTimeZone]];
NSDateComponents *dateComps = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:date];
NSDate *daydate = [calendar dateFromComponents:dateComps];
myObject.date = date;
myObject.daydate = daydate;
然后,您可以操作取回(2个选项)
备选案文1:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"myObject" inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"daydate"];
NSExpression *functionExpression = [NSExpression expressionForFunction:@"count:" arguments:@[keyPathExpression]];
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setName:@"count for this daydate:"];
[expressionDescription setExpression:functionExpression];
[expressionDescription setExpressionResultType:NSDoubleAttributeType];
NSAttributeDescription *attributeDesc = (entity.attributesByName)[@"daydate"];
[request setPropertiesToFetch:@[attributeDesc, expressionDescription]];
[request setPropertiesToGroupBy:@[attributeDesc]];
[request setResultType:NSDictionaryResultType];
NSError *error = nil;
NSArray *array = [self.managedObjectContext executeFetchRequest:request error:&error];
NSLog(@"array: %@", array);
NSLog(@"%lu", (unsigned long)array.count);
备选案文2:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"myObject" inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
request.returnsDistinctResults = YES;
request.propertiesToFetch = @[@"daydate"];
request.resultType = NSDictionaryResultType;
NSError *error = nil;
NSArray *array = [self.managedObjectContext executeFetchRequest:request error:&error];
NSLog(@"array: %@", array);
NSLog(@"array count: %lu", (unsigned long)array.count);
我在我的一个应用程序中也遇到了同样的问题,我从来没有找到一个谓词可以帮我解决这个问题 我目前查看实体中的所有对象,计算每个日期的日期,然后返回一个唯一日期数组。我正在考虑为我的实体添加一个day属性,但尚未测试该概念 下面是我目前使用的代码。注:
Game
Game
,我想转换为唯一天数的属性是startDateTime
[uniqueDays count]
)+ (NSArray *)allGameStartDaysInManagedObjectContext:(NSManagedObjectContext *)moc {
__block NSArray *gameDates;
// mod cannot be nil
NSParameterAssert(moc);
[moc performBlockAndWait:^{
NSError *error;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Game"];
NSArray *game = [moc executeFetchRequest:request error:&error];
// Check for errors
if (!game) {
// Log errors
NSLog(@"[%@ %@ %d]", NSStringFromClass([self class]), NSStringFromSelector(_cmd), __LINE__);
NSLog(@"Core Data error: %@", error.localizedDescription);
NSArray *errors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
if (errors != nil && errors.count > 0) {
for (NSError *error in errors) {
NSLog(@" Error: %@", error.userInfo);
}
} else {
NSLog(@" %@", error.userInfo);
}
gameDates = nil;
} else if (game.count) {
// Array to hold (at most) all the days of the games in the database
NSMutableArray *days = [[NSMutableArray alloc] initWithCapacity:game.count];
for (Game *games in game) {
// Add only the day to the array
[days addObject:[Game convertDateTimetoDay:games.startDateTime]];
}
// Generate a unique set of dates
NSSet *uniqueDays = [NSSet setWithArray:days];
// Create an array from the unique set
NSMutableArray *uniqueGameDays = [NSMutableArray arrayWithArray:[uniqueDays allObjects]];
// Create the sort descriptor
NSSortDescriptor *sortOrder = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:NO];
// Sort the array
NSArray *sortedUniqueGameDays = [uniqueGameDays sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortOrder]];
gameDates = [sortedUniqueGameDays copy];
} else {
gameDates = nil;
}
}];
return gameDates;
}
+ (NSDate *)convertDateTimetoDay:(NSDate *)dateTimeToConvert {
// Get the year, month and day components (included era although this only applies to BCE)
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSEraCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:dateTimeToConvert];
// Add the date with only the selected components to the array
return [[[NSCalendar currentCalendar] dateFromComponents:components] dateByAddingTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT]];
}
从iOS 8开始,您可以对Swift使用
NSCalendar
一种方法是使用集合:
let array = ["15-06-2017", "15-08-2017", "15-06-2017", "14-06-2017",
"14-06-2017"]
let unique = Array(Set(array))
// ["15-06-2017", "15-08-2017", "14-06-2017"]
您还可以创建一个扩展来更明确地过滤数组:
extension Array where Element : Equatable {
var unique: [Element] {
var uniqueValues: [Element] = []
forEach { item in
if !uniqueValues.contains(item) {
uniqueValues += [item]
}
}
return uniqueValues
}
}
注
唯一数组将按未指定的顺序排列,您可能需要对其进行排序。有时候最好自己枚举,你可以编写一个扩展
做一个扩展可能会更好:
extension Array where Element : Hashable {
var unique: [Element] {
return Array(Set(self))
}
}
可能有更优化的方法来做你想做的事情,但这种方法既快捷又简单。如果用户旅行到不同的时区,这种方法将被打破
NSDate
始终存储一个完整的时间,即使您对其进行操作,使某些值为零。它实际上只是NSTimeInterval
的包装,存储自引用日期起的秒数。如果您坚持使用UTC而不是本地时区,这可能没问题。谢谢!为我工作!我不知道应该在哪里添加NSDate+Utils.m,我需要相同的来获得唯一的年份。使用dateWithoutTime方法创建Utils类别。在您的例子中,NSDateComponents*components=[calendar components:NSYearCalendarUnit fromDate:self]代码>@Sauvage您知道这行代码中使用的技术描述吗NSString*key=@“date.dateWithoutTime”;您在类别中创建的方法似乎在这里被调用。这项技术有名字吗?我不确定它有名字。我们按日期将所有物体分成若干部分。使用这种方法,我们可以为每一个都设定特定的值。