在抓取请求中显示不同的结果,按属性分组,并计算该属性的总计 [英] Show distinct results in fetch request, group by an attribute and calculate the total for that attribute

查看:108
本文介绍了在抓取请求中显示不同的结果,按属性分组,并计算该属性的总计的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

场景:

我有一个费用跟踪iOS应用程序,我有一个视图控制器DashBoardViewController(表视图控制器 - 与FRC)给定周,一个月或一年的费用/收入,并将其显示为节头部标题,例如:(2012年10月1日 - 10月7日),并且根据该特定周或月显示费用/收入ROWS和相关东西或年。

I have an expense tracking iOS Application and I have a view controller called "DashBoardViewController" (table view controller - with FRC) which would basically categorize my expenses/incomes for a given week, a month, or year and display it as the section header title for example : (Oct 1- Oct 7, 2012) and it shows expenses/incomes ROWS and related stuff according to that particular week or month or year.

我的问题:

我想要完成的是:

假设我在三个不同的日期(分别是11月11日,14月11日,2012年11月16日)中保存了3个名为Auto的新费用。

Suppose I save 3 new expenses with SAME category named "Auto" on three different dates(11 nov, 14 nov, 16 nov, 2012 respectively).

在我的视图控制器中,我想在表视图中将该类别自动显示为一行,但它应该只显示为一行,而不是三次,因为我节省了三个费用(类别自动),总金额应该加起来为我保存的所有3个费用(对于特定类别)。类似以下屏幕截图。

In my view controller, I want to display that category "Auto" as a row in table view but it should appear only as ONE ROW and NOT THREE TIMES as I saved three expenses (with category "Auto") and the total amount should be added up for all the 3 expenses I saved (for that particular category). Something like the following screenshot.

>

我写了一些代码位,它为同一类别提供了三个ROWS,而不是我真正想要的(同一类别的一个ROWS),我不知道如何计算总为他们?应该是与NSPredicate在这里或抓取结果控制器相关的东西。
任何帮助将非常感激。

I have written some code bit it gives me THREE ROWS for the SAME CATEGORY and not what I actually want (ONE ROW for SAME CATEGORY) and I don't know how I would calculate the total for them? Should be something related to NSPredicate here or fetched results controller. Any help would be highly appreciated.

- (void)userDidSelectStartDate:(NSDate *)startDate andEndDate:(NSDate *)endDate
{
    AppDelegate * applicationDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext * context = [applicationDelegate managedObjectContext];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
  // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Money" inManagedObjectContext:context];
   [fetchRequest setEntity:entity];

  // Set the batch size to a suitable number.
   [fetchRequest setFetchBatchSize:20];

   NSPredicate *predicateDate = [NSPredicate predicateWithFormat:@"(date >= %@) AND (date <= %@)", startDate, endDate];

// Edit the sort key as appropriate.

  typeSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"type" ascending:YES]; // type refers to an expense or income.

  dateSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:YES];

  if(self.choiceSegmentedControl.selectedIndex == 0)  // UISegment Control for "Sorting Category"
  {
      NSPredicate *predicateCategory = [NSPredicate predicateWithFormat:@"cat == %@", @""];

      NSArray * subPredicates = [NSArray arrayWithObjects:predicateCategory, predicateDate, nil];

      NSPredicate * compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];

      [fetchRequest setPredicate:compoundPredicate];

      choiceSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"cat" ascending:NO];
   }

   NSArray * descriptors = [NSArray arrayWithObjects:typeSortDescriptor, dateSortDescriptor, choiceSortDescriptor, nil];

   [fetchRequest setSortDescriptors:descriptors];
   [fetchRequest setIncludesSubentities:YES];


   if(_fetchedResultsController)
   {
       [_fetchedResultsController release]; _fetchedResultsController = nil;

   }

   // Edit the section name key path and cache name if appropriate.
   // nil for section name key path means "no sections".
  _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:@"type" cacheName:nil];

  _fetchedResultsController.delegate = self;

  NSError *anyError = nil;

  if(![_fetchedResultsController performFetch:&anyError])
  {
      NSLog(@"error fetching:%@", anyError);
  }

  __block double totalAmount = 0;

  [[self.fetchedResultsController fetchedObjects] enumerateObjectsUsingBlock: ^void (Money *money, NSUInteger idx, BOOL *stop) {

    totalAmount += [[money amount] doubleValue];
  }];

  [fetchRequest release];

  //Finally you tell the tableView to reload it's data, it will then ask your NEW FRC for the new data
  [self.dashBoardTblView reloadData];

  self.startDate = startDate;
  self.endDate = endDate;

}



我想到使用NSDictionaryResultType,但这是一个问题, FRC我已经使用(对于节名,填充表视图等)

I thought to use NSDictionaryResultType but that's giving a problem with the FRC i have used ( for section names, filling up the table view etc.)

我循环通过FRC的代码给我的总金额)但是我想要每个类别的总金额(例如:类别汽车的总数,类别娱乐的总数)。请帮助我,我完全被困在这里。

The code where I loop through the FRC gives me the total amount (for income and expenses) BUT I want the total amount for each category (example: total for category "Auto", total for category "Entertainment"). Please help me, I am totally stucked up here.

推荐答案

我不认为你可以按摩你的FRC的对象。 NSPredicate只是过滤这种对象返回它不会从数据创建新的。

I don't think you can massage your FRC into returning the kind of objects you need. NSPredicate just filters the kind of objects to return it does not create new ones from the data.

但是,您可以获取按日期过滤的您的资金对象,然后使用 KVC Collection Operators 如下:

However, you can fetch the your money objects filtered by the date and then calculate the data from the array of money objects using KVC Collection Operators like so:

NSArray *moneyObjectsFilteredbyDate = [self.fetchedResultsController fetchedObjects]
NSArray *categoryStrings = [moneyObjectsFilteredbyDate valueForKeyPath:@"@distinctUnionOfObjects.cat"];
NSArray *sortedCategoryStrings = [categoryStrings sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

NSMutableArray *aggregatedDataObjects = [NSMutableArray array];
for (NSString *aCategoryString in sortedCategoryStrings) {
    NSPredictate *categoryPredicate = [NSPredicate predicateWithFormat:@"cat == %@", aCategoryString];
    NSArray *moneyWithThisCategory  = [moneyObjectsFilteredByDate filteredArrayUsingPredicate:categoryPredicate];
    NSNumber *sum = [moneyWithThisCategory valueForKeyPath:@"@sum.amount"];
    [aggregatedDataObjects addObject:@{@"category" : aCategoryString, @"sum" : sum, @"individualExpenses" : moneyWithThisCategory}];
} 

当然,您可以在方法的某些部分表单元格(如计算总和本身),但我希望它给你一个想法。但我不认为你可以使用SQL查询或类似的形式的谓词来创建新的数据结构。

Of course, you could do parts of the in the method where you configure the table cell (like calculating the sum itself), but I hope it gives you an idea. But I don't think you can use the predicate in a form of an SQL query or similar to create new data structure.

你可以做的其他事情:使类别您的Core Data模型的单个对象,并添加货币对象和类别对象之间的关系。然后你可以获取类别对象。虽然您必须按日期筛选类别的费用。

Something else you could do: Make the category an individual object of your Core Data model and add a relationship between moneyobjects and Category objects. Then you can just fetch category objects. Although you would then have to filter the expense for a category by the dates.

这篇关于在抓取请求中显示不同的结果,按属性分组,并计算该属性的总计的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆