Core Dataを使用して、問題が発生しました。属性「amount」を持つエンティティ「Movement」があります。すべてのインスタンスのすべての「量」の合計を作成するにはどうすればよいですか?使い方を理解したいNSExpressionDescription
のですが、それで十分NSSet
です。
3 に答える
managedObjectContextを持つ:
NSManagedObjectContext *managedObjectContext = ...
リターンタイプディクショナリを使用してフェッチリクエストを作成します。
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([Movement class])];
fetchRequest.resultType = NSDictionaryResultType;
次に、合計を計算するための式の説明を作成します。
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
expressionDescription.name = @"sumOfAmounts";
expressionDescription.expression = [NSExpression expressionForKeyPath:@"@sum.amount"];
expressionDescription.expressionResultType = NSDecimalAttributeType;
フェッチするリクエストプロパティを設定します。
fetchRequest.propertiesToFetch = @[expressionDescription];
必要に応じて、述語を設定することもできます。
最後に、リクエストを実行して、1つのキー(@ "sumOfAmounts")を持つディクショナリを含む配列を取得します。その値は、金額の合計を持つNSNumberです。
NSError *error = nil;
NSArray *result = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (result == nil)
{
NSLog(@"Error: %@", error);
}
else
{
NSNumber *sumOfAmounts = [[result objectAtIndex:0] objectForKey:@"sumOfAmounts"];
}
乾杯
これは、とを使用して管理対象オブジェクトの属性を合計するSwiftの例です。この例では、管理対象オブジェクトに名前が付けられ、合計する属性が 。であると想定しています。NSExpression
NSExpressionDescription
Movement
amount
例:
func sumAmount() -> Double {
var amountTotal : Double = 0
// Step 1:
// - Create the summing expression on the amount attribute.
// - Name the expression result as 'amountTotal'.
// - Assign the expression result data type as a Double.
let expression = NSExpressionDescription()
expression.expression = NSExpression(forFunction: "sum:", arguments:[NSExpression(forKeyPath: "amount")])
expression.name = "amountTotal";
expression.expressionResultType = NSAttributeType.doubleAttributeType
// Step 2:
// - Create the fetch request for the Movement entity.
// - Indicate that the fetched properties are those that were
// described in `expression`.
// - Indicate that the result type is a dictionary.
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Movement")
fetchRequest.propertiesToFetch = [expression]
fetchRequest.resultType = NSFetchRequestResultType.dictionaryResultType
// Step 3:
// - Execute the fetch request which returns an array.
// - There will only be one result. Get the first array
// element and assign to 'resultMap'.
// - The summed amount value is in the dictionary as
// 'amountTotal'. This will be summed value.
do {
let results = try context.fetch(fetchRequest)
let resultMap = results[0] as! [String:Double]
amountTotal = resultMap["amountTotal"]!
} catch let error as NSError {
NSLog("Error when summing amounts: \(error.localizedDescription)")
}
return amountTotal
}
手順の追加の説明:
ステップ1-変数を作成しNSExpressionDescription
ます。これNSExpressionDescription
は、引数に適用される関数のタイプを示します。合計関数がamount属性に適用されています。
expression.expression = NSExpression(forFunction: "sum:",
arguments:[NSExpression(forKeyPath: "amount")])
argumentsパラメータが配列であることに注意してください。配列にはさまざまなタイプの式を渡すことができますが、この場合はamount
属性のみが必要です。
ステップ2-フェッチ要求はここで確立されます。結果タイプがディクショナリとして指定されていることに注意してくださいfetchRequest.resultType = NSAttributeType.DictionaryResultType
。ステップ3では、合計値にアクセスするためのキーとしてのexpression.name
値を使用します。amountTotal
ステップ3-フェッチリクエストを実行すると、1つの要素の配列が返されます。要素は、私たちがキャストする辞書になります[String:Double]
:let resultMap = results[0] as! [String:Double]
。ステップ1で、がDoubleになることを示したため、ディクショナリの値はexpression.expressionResultType
Doubleです。
amountTotal
最後に、キーに関連付けられたディクショナリ値を呼び出して合計にアクセスします。resultMap["amountTotal"]!
参照:
最良の方法は、特定の値に対してフェッチを使用し、NSExpressionDescriptionにsum:
関数を提供することです。
フェッチを実行すると、キーが式の説明と一致し、値が式の結果であるディクショナリを含む1つの要素の配列が取得されます。この場合、sum
式で指定された属性の合計が値になるキーを取得します。