使用NSExpression expressionForSubquery有条件地对数据求和
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用NSExpression expressionForSubquery有条件地对数据求和相关的知识,希望对你有一定的参考价值。
我有下表,我想获取fileSize字段数据的总和,isSelectedForSync标志将为YES。
这是DigitalLibrary表属性
TableName:DigitalLibrary
属性及其类型:
- digitalLibraryID(NSNumber)
- fileName(NSString)
- connectType(NSString)
- fileSize(NSNumber - doubleValue)
- isSelectedForSync(NSNumber - BOOL)
- isSync(NSNumber - BOOL)
我想获取isSelectedForSync标志为YES的文件计数。还需要获取isSelectedForSync的fileSize的总和
我在NSExpression下面尝试,但没有得到我想要的东西。它也给我错误。
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription* entityDescription = [NSEntityDescription entityForName:@"DigitalLibrary" inManagedObjectContext:self.managedObjectContext];
NSDictionary *entityDict = [entityDescription propertiesByName];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"isSync == %@ && isSelectedForSync == %@",[NSNumber numberWithBool:NO], [NSNumber numberWithBool:YES]];
[fetchRequest setPredicate:predicate];
[fetchRequest setEntity:entityDescription];
[fetchRequest setResultType:NSDictionaryResultType];
[fetchRequest setPropertiesToGroupBy:[NSArray arrayWithObjects:[entityDict objectForKey:@"connectType"], nil]];
//AllPhotoCount
NSExpression *countExpression = [NSExpression expressionForFunction:@"count:"
arguments:@[[NSExpression expressionForKeyPath:@"connectType"]]];
NSExpressionDescription *fileCountExpressionDescription = [[NSExpressionDescription alloc] init];
[fileCountExpressionDescription setName:@"filesCount"]; // Choose an appropriate name here!
[fileCountExpressionDescription setExpression:countExpression];
[fileCountExpressionDescription setExpressionResultType:NSInteger32AttributeType];
// //Selected Photo Count
NSExpression *selectedFileExpression = [NSExpression expressionForFunction:@"sum:"
arguments:@[[NSExpression expressionForKeyPath:@"isSelectedForSync"]]];
NSExpressionDescription *selectedFilesExpressionDescription = [[NSExpressionDescription alloc] init];
[selectedFilesExpressionDescription setName:@"selectionCount"]; // Choose an appropriate name here!
[selectedFilesExpressionDescription setExpression:selectedFileExpression];
[selectedFilesExpressionDescription setExpressionResultType:NSInteger32AttributeType];
NSString *shadowVar = @"";
//Sum Of FileSize which file selected
// NSExpression *keyPathSelectedFileSizeTotalExpression = [NSExpression expressionForKeyPath:@"fileSize"];
NSExpression *selectedFileSizeTotalExpression = [NSExpression expressionForFunction:@"sum:"
arguments:@[[NSExpression expressionForKeyPath:@"fileSize"]]];
NSExpression *totalselectedFileSizeExpression = [NSExpression expressionForSubquery:selectedFileSizeTotalExpression usingIteratorVariable:shadowVar predicate:[NSPredicate predicateWithFormat:@"isSelectedForSync == %@",[NSNumber numberWithBool:YES]]];
NSExpressionDescription *selectedFileSizeTotalExpressionDescription = [[NSExpressionDescription alloc] init];
[selectedFileSizeTotalExpressionDescription setName:@"selectedFileSizeTotal"];
[selectedFileSizeTotalExpressionDescription setExpression:totalselectedFileSizeExpression];
[selectedFileSizeTotalExpressionDescription setExpressionResultType:NSInteger64AttributeType];
[fetchRequest setPropertiesToFetch:@[[entityDict objectForKey:@"connectType"], fileCountExpressionDescription, selectedFileSizeTotalExpressionDescription]];
NSLog(@"2nd shadowVar:%@",shadowVar);
NSError* error = nil;
NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
如果我删除'selectedFileSizeTotalExpressionDescription',上面的代码工作得很好,但如上所述需要selectedFileSizeTotalExpressionDescription。
我在如何使用NSExpression expressionForSubquery方法时非常困惑。
以下是包含在DigitalLibrary表中的数据:
+-----------+--------------------+--------------+------------+
|fileSize |isSelectedForSync |connectType |fileName |
+-----------+--------------------+--------------+------------+
|1000 |0 |Image |temp1.png |
+-----------+--------------------+--------------+------------+
|200 |1 |Image |tmp.png |
+-----------+--------------------+--------------+------------+
|400 |1 |Image |tmp23.png |
+-----------+--------------------+--------------+------------+
|20000 |1 |Video |test.mp4 |
+-----------+--------------------+--------------+------------+
|3000 |1 |Audio |temp2.mp3 |
+-----------+--------------------+--------------+------------+
|15000 |0 |Video |test12.mp4 |
+-----------+--------------------+--------------+------------+
|3500 |0 |Audio |temp12.mp3 |
+-----------+--------------------+--------------+------------+
我想得到以下结果:
+----------------+-------------------+--------------+----------------+------------------+
|TotalFileSize |selectedFileSize |connectType |totalFileCount |selectedFileCount |
+----------------+-------------------+--------------+----------------+------------------+
|1400 |600 |Image |3 |2 |
+----------------+-------------------+--------------+----------------+------------------+
|35000 |20000 |Video |2 |1 |
+----------------+-------------------+--------------+----------------+------------------+
|6500 |3000 |Audio |2 |1 |
+----------------+-------------------+--------------+----------------+------------------+
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([DigitalLibrary class])];//
NSPredicate * imageTypePredicate = [NSPredicate predicateWithFormat:@"connectType ==[c] Image"];
[fetchRequest setPredicate:imageTypePredicate];
NSArray * imageTypeFilteredArray = [context executeFetchRequest:fetchRequest error:nil];
NSArray * imageFileSizeArray = [imageTypeFilteredArray valueForKey:@"fileSize"];
double totalValue = 0.0;
for (NSNumber * eachFileSize in imageFileSizeArray)
{
totalValue += [eachFileSize doubleValue];
}
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"isSelectedForSync == YES"];
NSArray * selectedImageFileSizeArray = [imageTypeFilteredArray filteredArrayUsingPredicate:predicate];
double totalSelectedValue = 0.0;
for (NSNumber * eachFileSize in selectedImageFileSizeArray)
{
totalSelectedValue += [eachFileSize doubleValue];
}
同样可以用于视频和音频。
以上是关于使用NSExpression expressionForSubquery有条件地对数据求和的主要内容,如果未能解决你的问题,请参考以下文章
使用 NSExpression 时捕获 NSInvalidArgumentException 的正确方法 [重复]
NSExpression 使用 sqrt: 函数导致 NSInvalidArgumentException
如何使用 NSExpression 使用自定义函数设置 NSFetchRequest propertiesToFetch