2011-11-15 18 views
2

CoreDataに整数値の列があります。その結果を取得する際には、列の値を数値で減算します。CoreData数学関数

何かのような:columnValue - someNumber(この番号は、ユーザによって入力される)

私はこのためにNSPredicateを使用する必要があります知っているが、そのための関数や構文があるかどう認識しませんよ。

ここでもう1つは、すべての列の値を繰り返し、「someNumber」で減算することです。しかし、私はこれを行うためのより効率的な方法があるべきだと思います。


編集:コード@ salo.dmの答え

 - (NSDictionary *)myFetchResults { 
    //Predicate works fine 
      NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:pred1, pred2, nil]]; 

      /*Sort Descroptor - Sorting by 4 columns*/ 
      NSSortDescriptor *sortDesc1 = [NSSortDescriptor sortDescriptorWithKey:@"Column1" ascending:YES]; 
      NSSortDescriptor *sortDesc2 = [NSSortDescriptor sortDescriptorWithKey:@"Column2" ascending:YES]; 
      NSSortDescriptor *sortDesc3 = [NSSortDescriptor sortDescriptorWithKey:@"Column3" ascending:YES]; 
      NSSortDescriptor *sortDesc4 = [NSSortDescriptor sortDescriptorWithKey:@"Column4" ascending:YES]; 

      /*Get Data*/ 
      MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; 
      NSManagedObjectContext *context = [appDelegate managedObjectContext]; 

      NSEntityDescription *entity = [NSEntityDescription entityForName:@"TableName" inManagedObjectContext:context]; 
      NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
      [fetchRequest setEntity:entity]; 
      [fetchRequest setPredicate:predicate]; 
      [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDesc1, sortDesc2, sortDesc3, sortDesc4, nil]]; 

      NSArray *listData = [context executeFetchRequest:fetchRequest error:nil]; 


      /*Create subtract expression*/ 
      NSExpressionDescription *subExp1 = [[NSExpressionDescription alloc] init]; 
     [subExpLatitude setName:@"subtraction1"]; 
     [subExpLatitude setExpression:[NSExpression expressionForFunction:@"from:subtract:" 
                   arguments:[NSArray arrayWithObjects: 
                      [NSExpression expressionForKeyPath:@"Column3"], 
                      [NSExpression expressionForConstantValue:[NSNumber numberWithDouble:someNumber1]], 
                      nil]]]; 
      [subExp1 setExpressionResultType:NSDoubleAttributeType]; 

      NSExpressionDescription *subExp2 = [[NSExpressionDescription alloc] init]; 
     [subExpLongitude setName:@"subtraction2"]; 
     [subExpLongitude setExpression:[NSExpression expressionForFunction:@"from:subtract:" 
                    arguments:[NSArray arrayWithObjects: 
                       [NSExpression expressionForKeyPath:@"Column4"], 
                       [NSExpression expressionForConstantValue:[NSNumber numberWithDouble:someNumber2]], 
                       nil]]]; 
      [subExp2 setExpressionResultType:NSDoubleAttributeType]; 

      /*Get difference data*/ 
      [fetchRequest setResultType:NSDictionaryResultType]; 
      [fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:subExp1, subExp2, nil]]; 

      NSArray *listDifference = [context executeFetchRequest:fetchRequest error:nil]; 

      NSLog(@"Subtraction 1: %@", [[listDifference objectAtIndex:0] objectForKey:@"subtraction1"]); 
      NSLog(@"Subtraction 2: %@", [[listDifference objectAtIndex:0] objectForKey:@"subtraction2"]); 

      NSMutableDictionary *dictResult; 
      [dictResult setObject:listData forKey:@"Data"] 
      [dictResult setObject:listDifference forKey:@"Difference"] 

     return dictResult; 
} 

編集から:これは動作しません

coredataオブジェクトを取得します。

​​

は(これが正しい方法であると仮定すると)、それは作業を取得するには、以下のように変更する

NSExpressionDescription *expEntity = [[NSExpressionDescription alloc] init]; 
    [expEntity setName:@"TableNameEntity"]; 
    [expEntity setExpression:[NSExpression expressionForEvaluatedObject]]; 
    [expEntity setExpressionResultType:NSObjectIDAttributeType]; 

を持っていた私はsetPropertiesToFetchリストにexpEntityを追加しました。今私は辞書の2つの値を取得します。

{ 
    TableNameEntity = "0x5e22120 <x-coredata://1A659A52-9321-4ACD-992B-04F20E7BDCED/TableNameEntity/p1640>"; 
    subtractionValue = "-24.13"; 
} 

辞書からTableNameEntityにアクセスしてアクセスしようとすると、アプリケーションがクラッシュします。ここで

TableNameEntity *tableEntity = (TableNameEntity *)[dict objectForKey:@"TableNameEntity"]; 
tableEntity.column1 //This is not the exact code. But this operation crashes with error 

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_NSObjectID_48_0 column1]: unrecognized selector sent to instance 0x5e22120' 

あなたが気づいた場合、キーTableNameEntityの値は引用符に含まれているので、私はその文字列として返される推測されます。

私が間違ったことを修正できるかどうかを確認してください。


代替語で辞書の列の値を取得しようとしました。ここ(これはうまくいく)です。しかし、私はそれが良いアプローチではないと思います。

- (NSArray *)myFetchResults 
{ 
    NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    request.entity = [NSEntityDescription entityForName:@"myEntity" inManagedObjectContext:myContext]; 

    request.resultType = NSDictionaryResultType; 

    NSExpressionDescription *subExDescr = [[NSExpressionDescription alloc] init]; 
    [subExDescr setName:@"subtraction"]; 
    [subExDescr setExpression:[NSExpression expressionForFunction:@"subtract:from:" 
                  arguments:[NSArray arrayWithObjects: 
                    [NSExpression expressionForConstantValue:[NSNumber numberWithInt:someNumber]], 
                    [NSExpression expressionForKeyPath:@"myAttribute"], 
                    nil]]]; 
    [subExDescr setExpressionResultType:NSInteger64AttributeType]; 

    request.propertiesToFetch = [NSArray arrayWithObject:subExDescr, nil]; 

    NSError *err = nil; 
    NSArray *results = [self.moContext executeFetchRequest:request error:&err]; 
    [request release]; 
    [err release]; 

    return results; 
} 

フェッチ結果は、辞書の配列になります。次のように

[fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:subExp1, @"column1", @"column2", ... @"columnN" nil]]; 

答えて

4

あなたはフェッチ要求に計算を行うことができます。次のように列のn番目の値の結果にアクセスできます。

NSArray *results = [self myFetchResults]; 
NSDictionary *nthDict = [results objectAtIndex:n]; 
NSInteger nthValue = [nthDict objectForKey:@"subtraction"]; 

このコードはテストされていません。つまり、私はそれがコラムのすべての項目に作用すると信じています。選択した項目だけを操作したい場合は、操作する項目を選択するために述部を追加することができます。

NSExpressionのドキュメントを参照して、さまざまな操作をすべて作成することもできます。このクラスは少し高密度ですが、Appleのマニュアルには、その使い方を理解するのに役立つコードスニペットがいくつかあります。上の例では、フェッチ要求に組み込む方法を示しています。

EDIT:CORRECTION

エンティティは、当然のことながら、フェッチ要求で指定する必要があります。私は最初にそれを残しましたが、コードを修正しました。


EDIT:レスポンス

をコメントに私はあなたが求めているものを理解していないが、これはそれかもしれません。次のように表現記述を作成することができます

NSExpressionDescription *expLatitude = [[NSExpressionDescription alloc] init]; 
[expLatitude setName:@"latitude"]; 
[expLatitude setExpression:[NSExpression expressionForKeyPath:@"Column3"]]; 
[expLatitude setExpressionResultType:NSDoubleAttributeType]; 

NSExpressionDescription *expEntity = [[NSExpressionDescription alloc] init]; 
[expEntity setName:@"TableNameEntity"]; 
[expEntity setExpression:[NSExpression expressionForKeyPath:@"objectID"]]; 
[expEntity setExpressionResultType:NSObjectIDAttributeType];} 

その後、あなたはさらに2つのオブジェクトとして、propertiesToFetch配列に追加します。フェッチ結果の各ディクショナリには、緯度と、同じ緯度から得られる減算と、その緯度を含むエンティティの対応するobjectIDが含まれるようになりました。辞書はソート記述子に従って結果配列内で順序付けされます。 (私はobjectID式を試していませんが、うまくいくはずです)

基本的に、結果は、同じ述語と同じソート記述子を持つ伝統的なフェッチ要求と全く同じ順序で並べられます。フェッチ要求の場合、デフォルトの結果タイプはNSManagedObjectResultTypeです。

これがあなたの質問に答えることを願っています。そうでなければ、もう一度尋ねることを躊躇しないでください。しかし、今私にとって睡眠時間なので、答えに時間がかかるかもしれません。


EDIT:レスポンスオブジェクトIDを取得するには、正しい表現を見つけることに

グッドキャッチ 'をCOREDATAオブジェクトを取得する' に! (それを見て、私が今提示した表現は明らかに間違っているように見えます)。

例外的に、それは理にかなっています。フェッチ結果に返される値は管理対象オブジェクト自体ではなく、管理対象オブジェクトのIDのみです。管理対象オブジェクトにアクセスするには、私は次のように動作するはずだと思う:

NSManagedObjectID *myObjectID = [dict objectForKey:@"TableNameEntity"]; 
TableNameEntity *tableEntity = (TableNameEntity *)[context objectWithID:myObjectID]; 
tableEntity.column1 

上記contextはNSManagedObjectContextです。

しかし、私はあなたの最終的な解決策を好むと思います。 NSExpressionDescriptionsとpropertiesToFetch配列のプロパティを組み合わせることができるかどうかはわかりませんでした。知っておいてよかった!

さらに重要なことは、フェッチで必要なすべてのプロパティを取得する方が、フェッチからobjectIDだけを取得して後でプロパティを取得するよりも高速かもしれないことです。 objectIDを取得することは一般に、エンティティのフォルトを起動しません。私は、あなたがそのプロパティにアクセスすると、後で不具合が発覚すると信じています。最初のプロパティにアクセスすると1回、またはプロパティごとに1回、複数回起動します。 (フォールティングの説明については、Firing Faultsを参照してください。)

私がお勧めするのは、propertiesToFetchで必要なすべてのプロパティを含むことが最善の方法です。 (オブジェクトIDを取得してみることもできますが、速度が遅い場合はフェッチのすべてのプロパティを取得することに戻ってください)

フェッチ要求と表現の記述が不適切です。あなたは文法の権利を得るためにそれらと少し遊ぶ必要があります。あなたはとてもうまくやっているようです。

+0

お返事ありがとうございます。私はいくつかの疑問を持っています。 ---その結果、私は '列の値'と 'someNumber'の違いを持つ辞書を取得します。違いとDBオブジェクト(行)を含む結果が得られる方法はありますか?現時点では、2つの結果セット(配列)を取得するようにコーディングしました。 1つはDBオブジェクトを含み、もう1つは違いを含みます。質問の編集としてコードを投稿します。 – Sahil

+0

salo.dm:質問の「Edit:Get coredata object」にチェックを入れてください。ありがとう! – Sahil

+0

編集した返信を確認してください。 –