2

いくつかのインスタンスがNSArray含まれています。NSDictionaryそれぞれNSDictionaryに、他のフィールドの中でも、という名前のオブジェクトratingと1つnumberOfVotes(両方ともint)があります。rating/でソートされるように配列をソートするにはどうすればよいnumberOfVotesですか?より一般的には、上記のような操作を行って並べ替えることはできますか?または、各操作の値を使用してそれぞれに別のオブジェクトを追加NSDictionaryし、それで並べ替える方がよいでしょうか。

ありがとう

編集-私は以下を追加しました。まだ正しく並べ替えられていません。1つの質問:これは私の配列内の3つ以上のオブジェクトに対して機能する必要があります。(オブジェクトの数は異なります)

    [sortedArray sortedArrayUsingComparator:^NSComparisonResult(id dict1, id dict2)
{
    MyObj *obj1 = (MyObj *)dict1;
    MyObj *obj2 = (MyObj *)dict2;

    int rating1 = obj1.rating.intValue;
    int rating2 = obj2.rating.intValue;

    int number1 = obj1.number_of_votes.intValue;
    int number2 = obj2.number_of_votes.intValue;

    double key1 = ((double)rating1)/number1;
    double key2 = ((double)rating2)/number2;

    if (key1 < key2)
    {
        return NSOrderedDescending;
    }

    if (key2 < key1)
    {
        return NSOrderedAscending;
    }
    return NSOrderedSame;

}];
4

7 に答える 7

4

探している種類の複合ソートキーを使用するカスタムコンパレータを定義できます。並べ替えを実行する以外に、辞書にその並べ替えキーを含める正当な理由がない場合は、辞書に項目を追加しないでください。

array = [array sortedArrayUsingComparator: ^(id obj1, id obj2) {
    int rating1 = [[obj1 objectForKey:@"rating"] intValue];
    int numberOfVotes1 = [[obj1 objectForKey:@"numberOfVotes"] intValue];
    int rating2 = [[obj2 objectForKey:@"rating"] intValue];
    int numberOfVotes2 = [[obj2 objectForKey:@"numberOfVotes"] intValue];
    double key1 = ((double)rating1)/numberOfVotes1;
    double key2 = ((double)rating2)/numberOfVotes2;
    if (key1 > key2) {
        return (NSComparisonResult)NSOrderedDescending;
    }

    if (key1 < key2) {
        return (NSComparisonResult)NSOrderedAscending;
    }
    return (NSComparisonResult)NSOrderedSame;
}];

注:このsortedArrayUsingComparator:メソッドは、配列をその場でソートしません。代わりに、ソートされたコピーを返します。インプレースソートが必要な場合は、を使用してNSMutableArrayください。

于 2012-10-30T14:29:16.953 に答える
1

適切な方法は、このようなブロックを使用することです

NSArray *sortedArray;

sortedArray = [unsortedArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
    float first = [[(NSDictionary*)a objectForKey:@"rating"] floatValue]/
                      [[(NSDictionary*)a objectForKey:@"numberOfVotes"] floatValue];
    float second = [[(NSDictionary*)a objectForKey:@"rating"] floatValue]/
                      [[(NSDictionary*)a objectForKey:@"numberOfVotes"] floatValue];
return [[NSNumber numberWithFloat:first] compare: [NSNumber numberWithFloat:second]];
}];

あなたは比較するより多くの方法を見つけるかもしれません:

カスタムオブジェクトを含むNSMutableArrayを並べ替える方法は?

于 2012-10-30T14:32:20.267 に答える
0

データのフィルタリングは、コンピューティングにおける重要なタスクの1つです。

いくつかの方法で並べ替えることができます。

  1. NSPredicate

    ここで例を見ることができます

  2. NSSortDescriptor

    ここで例を見ることができます

  3. 正規表現

  4. セット操作

  5. Key-Valueコーディング

于 2012-10-30T14:35:04.110 に答える
0

求めるメソッドのファミリーには、接頭辞が付いていsortedArrayます。

関数(複数のオプションの1つ)については、以下を参照してください-[NSArray sortedArrayUsingFunction:context:]

于 2012-10-30T14:27:35.127 に答える
0

編集rating:で除算したい場合はnumberOfVotes、関数またはコンパレータブロックで並べ替えるか、辞書を計算メソッドを持つモデルオブジェクトに置き換える必要がありますrating / numberOfVotes

を使用しNSSortDescriptorます。

 NSArray *sorted = [array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:
    [NSSortDescriptor sortDescriptorWithKey:@"rating" ascending:YES],
    [NSSortDescriptor sortDescriptorWithKey:@"numberOfVotes" ascending:YES],
    nil]
 ];
于 2012-10-30T14:29:01.477 に答える
0

理想的には、やNSDictionaryのようなプロパティを持つカスタムオブジェクトに置き換える必要がratingありnumberOfVotesます。compare:次に、このカスタムオブジェクトでメソッドを宣言し、配列を並べ替えるセレクターとして使用できます。

ブロックコードを使用してオブジェクトを並べ替えることができますが、実装をカスタムオブジェクトに抽象化する方がはるかにクリーンです。

于 2012-10-30T14:36:01.037 に答える
0

ここでNSSortDescriptorを使用して、たとえば、複数のNSDictionnaries名を含む配列がdataArrayであるソートを行うことができます。

 NSSortDescriptor * descriptor = [[NSSortDescriptor alloc] initWithKey:rating
                            ascending:YES];
 NSArray * keyArrray = [NSArray arrayWithObjects:descriptor, nil];
 NSArray * sortedArray = [dataArray sortedArrayUsingDescriptors:keyArrray];

NSSortDescriptorを使用すると、任意のデータ型のキーと値のペアを並べ替えることができます。

于 2012-10-30T14:43:58.620 に答える