2017-11-10 9 views
-2

これまで、このソートファクトリでは、Invoice Itemオブジェクトの配列を1次元で並べ替えることができました。さまざまなソートディメンションは、SortItemオブジェクトのプロパティとして列挙型「状態」内に格納されます。ここには動作する実装があります。NSArrayを2次元でソートする - Objective-C

+(NSArray *)SortInvoiceItems:(NSArray *)items forSort:(SortItem*)sortItem forSecondarySort:(SortItem*)secondarySortItem { 
    NSArray * primary = [items sortedArrayUsingComparator:^NSComparisonResult(id a, id b) { 
     InvoiceItems *iiA = (InvoiceItems *)a; 
     InvoiceItems *iiB = (InvoiceItems *)b; 
     switch(sortItem.state) { 
      case DateAscending: 
      case DateDescending: { 
       return (sortItem.state == DateAscending) ? [iiA.transactionDate compare:iiB.transactionDate] : [iiB.transactionDate compare:iiA.transactionDate]; 
      } 
      case SumDescending: 
      case SumAscending: { 
       return (sortItem.state == SumAscending) ? [iiA.netInvoiceAmount compare:iiB.netInvoiceAmount] : [iiB.netInvoiceAmount compare:iiA.netInvoiceAmount]; 
      } 
      case UnitPriceDescending: 
      case UnitPriceAscending: { 
       return (sortItem.state == UnitPriceAscending) ? [iiA.uomNetAmt compare:iiB.uomNetAmt] : [iiB.uomNetAmt compare:iiA.uomNetAmt]; 
      } 
      default: 
       return 0; 
     } 
    }]; 

    return primary; 
} 

使用されていないメソッドシグネチャにsecondarySortパラメータを追加しました。私の目的は、このセカンダリディメンションによるソートを許可し、このセカンダリディメンションによってプライマリディメンションと同じ値を持つ請求書アイテムオブジェクトをソートすることです。

たとえば、2つのアイテムが同じ.transactionDateを持つ場合、これらの2つのアイテムは、さらに単価下落のような2番目のディメンションでソートされます。

編集:私は以下のように作業していますが、これを書くにはもっと簡潔な方法がありますか?

+(NSArray *)SortInvoiceItems:(NSArray *)items forSort:(SortItem*)sortItem forSecondarySort:(SortItem*)secondarySortItem { 

    NSSortDescriptor *primaryDescriptor; 
    NSSortDescriptor *secondaryDescriptor; 

    switch(sortItem.state) { 
     case DateAscending: 
      primaryDescriptor = [[NSSortDescriptor alloc] initWithKey:@"transactionDate" ascending:YES]; 
      break; 
     case DateDescending: 
      primaryDescriptor = [[NSSortDescriptor alloc] initWithKey:@"transactionDate" ascending:NO]; 
      break; 
     case SumAscending: 
      primaryDescriptor = [[NSSortDescriptor alloc] initWithKey:@"netInvoiceAmount" ascending:YES]; 
      break; 
     case SumDescending: 
      primaryDescriptor = [[NSSortDescriptor alloc] initWithKey:@"netInvoiceAmount" ascending:NO]; 
      break; 
     case UnitPriceAscending: 
      primaryDescriptor = [[NSSortDescriptor alloc] initWithKey:@"uomNetAmt" ascending:YES]; 
      break; 
     case UnitPriceDescending: 
      primaryDescriptor = [[NSSortDescriptor alloc] initWithKey:@"uomNetAmt" ascending:NO]; 
      break; 
     default: NSLog(@"invalid sort item"); 
    } 

    switch(secondarySortItem.state) { 
     case DateAscending: 
      secondaryDescriptor = [[NSSortDescriptor alloc] initWithKey:@"transactionDate" ascending:YES]; 
      break; 
     case DateDescending: 
      secondaryDescriptor = [[NSSortDescriptor alloc] initWithKey:@"transactionDate" ascending:NO]; 
      break; 
     case SumAscending: 
      secondaryDescriptor = [[NSSortDescriptor alloc] initWithKey:@"netInvoiceAmount" ascending:YES]; 
      break; 
     case SumDescending: 
      secondaryDescriptor = [[NSSortDescriptor alloc] initWithKey:@"netInvoiceAmount" ascending:NO]; 
      break; 
     case UnitPriceAscending: 
      secondaryDescriptor = [[NSSortDescriptor alloc] initWithKey:@"uomNetAmt" ascending:YES]; 
      break; 
     case UnitPriceDescending: 
      secondaryDescriptor = [[NSSortDescriptor alloc] initWithKey:@"uomNetAmt" ascending:NO]; 
      break; 
     default: NSLog(@"invalid sort item"); 
    } 

    NSArray *sortDescriptors = @[primaryDescriptor, secondaryDescriptor]; 
    return [items sortedArrayUsingDescriptors:sortDescriptors]; 
} 

SECOND EDIT:この問題を解決するために

+(NSArray *)SortInvoiceItems:(NSArray *)items forPrimarySort:(SortItem*)primary forSecondarySort:(SortItem*)secondary { 

    NSSortDescriptor *primaryDescriptor = [self GetDescriptorForSortItem:primary]; 
    NSSortDescriptor *secondaryDescriptor = [self GetDescriptorForSortItem:secondary]; 
    NSArray *sortDescriptors = @[primaryDescriptor, secondaryDescriptor]; 

    return [items sortedArrayUsingDescriptors:sortDescriptors]; 
} 

+(NSSortDescriptor *)GetDescriptorForSortItem:(SortItem*)sortItem { 
    switch(sortItem.state) { 
     case DateAscending: 
      return [[NSSortDescriptor alloc] initWithKey:kTransactionDateString ascending:YES]; 
     case DateDescending: 
      return [[NSSortDescriptor alloc] initWithKey:kTransactionDateString ascending:NO]; 
     case SumAscending: 
      return [[NSSortDescriptor alloc] initWithKey:kNetInvoiceAmount ascending:YES]; 
     case SumDescending: 
      return [[NSSortDescriptor alloc] initWithKey:kNetInvoiceAmount ascending:NO]; 
     case UnitPriceAscending: 
      return [[NSSortDescriptor alloc] initWithKey:kUOMNetAmount ascending:YES]; 
     case UnitPriceDescending: 
      return [[NSSortDescriptor alloc] initWithKey:kUOMNetAmount ascending:NO]; 
     default: 
      return [[NSSortDescriptor alloc] initWithKey:kTransactionDateString ascending:NO]; // default to date descending 
    } 
} 
+0

なぜ「難しい」のか分かりません。これはなぜNSSortDescriptorが解決しようとする問題ではないのですか? – matt

+0

それを知らなかった、マット。ありがとう。 うわー、あなたは文字通り、その本にその本を書きました。 –

+0

もう少し圧縮するには、渡された状態に基づいてディスクリプタを返すために2回呼び出すことができる別のメソッドにswitchステートメントを入れ替えます。 –

答えて

0

使用NSArrayさん-sortedArrayUsingDescriptors::これにリファクタリング。このメソッドを使用すると、NSSortDescriptorの配列を指定できます.2番目の配列は2次ソートとして機能します(3番目のソートがある場合は、3次ソートなど)。

-[NSSortDescriptor initWithKey:ascending:comparator:]を使用してコンパレータブロックを渡すと、NSSortDescriptorを作成できます。

0

ここで説明したように、NSSortDescriptorを使用してソートを構築:https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/SortDescriptors/Articles/Creating.html

EDIT:あなたのケースで を、あなたはソート記述子を決定state呼ばSortItemプロパティを持っているので、それはあなたの力であるため、しかし、それを構築するにはstateタイプをお勧めします。ソート記述子を状態そのものの一部にすることをお勧めします。そうすることで、ソートするときには何もする必要はありません。つまり、状態そのものがソート記述子を使用し、SortInvoiceItemsのスイッチを取り除くことができます。一般に、スイッチはあなたのオブジェクトタイプを正しく考案していないことを示唆する「悪臭」と見なすことができます。実際のオブジェクトに何かを切り替えるよりも何をすべきかを知らせるべきです。

+0

「NSSortDescriptor」はOPが既に質問に持っているようなコンパレータブロックを使って初期化できるので、KVCは必要ありません。 –

+0

右、いい点。 – matt

関連する問題