0

私は iOS に比較的慣れていません (私が明確でない場合、または問題が他の場所で対処されている場合は、事前に謝罪します)、基本を学ぶために多くのチュートリアルを実行しました。それでも、コアデータで次のことを行う際に問題に直面しています。

  • コア データを使用して DB からデータを取得し、並べ替えて表示する方法は理解していますが、計算して表示する必要がある属性 (DB のテーブルの一時的な属性) をプログラムで操作する方法がわかりません。ナビゲーションコントローラーに埋め込まれたテーブルビューコントローラー内の静的テーブルビューセル。

説明用: 2 つの変数( InputValue (integer) と inputDate (NSDate) )を持つテーブルがあり、1 年または 1 日ごとに毎日入力された値の平均/最小/最大を計算したいと考えています。これらの値は、テーブルビューの静的セル (セル内の各計算値) で毎回表示および更新されます。

編集:ここにテーブルビューコントローラーからいくつかのコードを追加しました:

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{

    //Configure the cell to show the user value as well as showing the date of input

    PVMesswert *wert = [self.fetchedResultsController objectAtIndexPath:indexPath];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
   [dateFormatter setDateFormat:@"dd.MM.yyyy"];
           cell.textLabel.text= [[NSString alloc] initWithFormat:@"%@ kWh", wert.inputValue];
    cell.detailTextLabel.text = [dateFormatter stringFromDate:wert.inputDate];

     }

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{    //should I have a different cell identifier for each row where I want to display a result of the calculations?
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell.
    [self configureCell:cell atIndexPath:indexPath];
    return cell;
}

- (NSFetchedResultsController *)fetchedResultsController
{


     if (_fetchedResultsController != nil) {
            return _fetchedResultsController;
        }

        // Create and configure a fetch request with the PVMesswert entity.


        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"PVMessWert" inManagedObjectContext:self.managedObjectContext];
        [fetchRequest setEntity:entity];

        // Create the sort descriptors array.

        NSSortDescriptor *datumsort = [[NSSortDescriptor alloc] initWithKey:@"inputDate" ascending:NO];

        NSSortDescriptor *valueDescriptor = [[NSSortDescriptor alloc] initWithKey:@"InputValue" ascending:YES];

        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:datumsort, /*authorDescriptor,*/ nil];
        [fetchRequest setSortDescriptors:sortDescriptors];

        // Create and initialize the fetch results controller.


        _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"dateToString" cacheName:@"Root"];

        _fetchedResultsController.delegate = self;

        // Memory management.

        return _fetchedResultsController;
    }    

したがって、私が持っている別のテーブルビューでは、次のようなものを表示したいと思います: avg/max/min Inputvalue per year (属性入力日付 NSDat に基づく)。NSExpression を使用する必要がありますか?その場合、どのように使用しますか?

4

2 に答える 2

1

この種の計算には集計関数を使用する必要があります。

比較的高速な 1 回のフェッチ リクエストで、すべての最大/最小/平均情報を取得できます。

集計関数のコードは次のようになります。

//Function expression generator
- (NSExpressionDescription*) aggregateFunction:(NSString*)function
                                    forKeyPath:(NSString*)keyPath
                                          name:(NSString*)name
                                    resultType:(NSAttributeType)resultType
{
    NSExpression* keyPathExpression = [NSExpression expressionForKeyPath:keyPath];
    NSExpression* funcExpression = [NSExpression expressionForFunction:function arguments:@[keyPathExpression]];
    NSExpressionDescription* expressionDescription  = [NSExpressionDescription new];
    [expressionDescription setName:name];
    [expressionDescription setExpression:funcExpression];
    [expressionDescription setExpressionResultType:resultType];
    return expressionDescription;
}

フェッチ リクエストは次のようになります。

//someValue is an Integer64 property
//someDate is a Date property
NSFetchRequest* r = [NSFetchRequest fetchRequestWithEntityName:@"Product"];
NSExpressionDescription* minValueField = [self aggregateFunction:@"min:"
                                                      forKeyPath:@"someValue"
                                                            name:@"minValue"
                                                      resultType:NSInteger64AttributeType];
NSExpressionDescription* avgValueField = [self aggregateFunction:@"average:"
                                                      forKeyPath:@"someValue"
                                                            name:@"avgValue"
                                                      resultType:NSInteger64AttributeType];
NSExpressionDescription* maxValueField = [self aggregateFunction:@"max:"
                                                      forKeyPath:@"someValue"
                                                            name:@"maxValue"
                                                      resultType:NSInteger64AttributeType];
NSExpressionDescription* minDateField = [self aggregateFunction:@"min:"
                                                     forKeyPath:@"someDate"
                                                           name:@"minVDate"
                                                     resultType:NSDateAttributeType];
NSExpressionDescription* avgDateField = [self aggregateFunction:@"average:"
                                                      forKeyPath:@"someDate"
                                                            name:@"avgDate"
                                                      resultType:NSDateAttributeType];
NSExpressionDescription* maxDateField = [self aggregateFunction:@"max:"
                                                     forKeyPath:@"someDate"
                                                           name:@"maxDate"
                                                     resultType:NSDateAttributeType];

[r setResultType:NSDictionaryResultType];
[r setPropertiesToFetch:@[minValueField,avgValueField,maxValueField,minDateField,avgDateField,maxDateField]];

NSArray* results = [context executeFetchRequest:r error:NULL];

注: * これにより、式を作成したパラメーターに
一致するキーを持つ単一の辞書オブジェクト内の情報が取得されます。 * を使用して結果セットの変更を「リアルタイム」で追跡することはできず、データベースの変更に合わせて計算を正確にする必要がある場合は、結果を更新する必要があります。 * 日と年でグループ化するには、日付フィールドから日と年を抽出して別のフィールド ( となど) に分割し、フェッチ リクエストでこれらのフィールドでグループ化する必要があります。name
NSFetchedResultsController
dayyear

[r setPropertiesToGroupBy:@[@"year"]];//to group by year alone

year取得するプロパティにを追加します。

編集:特定の年 (または年内の日) に関心がある場合は、年と日を日付から分離する必要があります (前に述べたように)。
次に、必要な年でフィルタリングする述語を設定するだけです。

[r setPredicate:[NSPredicate predicateWithFormat:@"year = %d",someYear]];
于 2013-07-12T03:52:05.587 に答える