iPhoneアプリ作成(7) 2次元配列を複数項目でソートする

ArrayにArrayを追加している2次元の配列(仮名:「Array-Array配列」)で、複数項目のソート用の比較関数を作ってみた。

ソートキーのキー数が変わるケースはよくあることで、ArrayにDictionayを追加している2次元の配列(仮名:「Array-Dictionay配列」)の場合は便利なメソッド(sortUsingDescriptors)が用意されていたが、「Array-Array配列」では見当たらなかった。(もしかして有ったりして...)

ということで、「Array-Array配列」でのソートするサンプルソースです。

◆使用例

	[array1 sortUsingFunction:stringSort3 context:(void*)"0,D,1,A"];

	0列目を降順、1列目を昇順でソート。

	[array1 sortUsingFunction:stringSort3 context:(void*)"0,D,1,A,2,A,3,A,4,A"];

	0列目を降順、1-4列目を昇順でソート。 列数と並びをペアで追加していきます。
◆ソース

// 1項目ソートで使用する比較関数
NSInteger stringSort1(id obj1, id obj2, void *context){
	NSInteger ret;
	if (context)ret = [[obj2 objectAtIndex:0] compare:[obj1 objectAtIndex:0]]; //降順
	else        ret = [[obj1 objectAtIndex:0] compare:[obj2 objectAtIndex:0]]; //昇順
	return ret;
}

// 2項目ソートで使用する比較関数
NSInteger stringSort2(id obj1, id obj2, void *context)
{
	NSInteger ret;
	//第1項目をチェックする
	ret = [[obj1 objectAtIndex:0] compare:[obj2 objectAtIndex:0]];
	//第2項目をチェックする
	if (ret == NSOrderedSame) {
	ret = [[obj1 objectAtIndex:1] compare:[obj2 objectAtIndex:1]];
	}
	//降順の場合、戻り値を反転させる
	if (context){
		if (ret == NSOrderedAscending)
			ret = NSOrderedDescending;
		else if (ret == NSOrderedDescending)
			ret = NSOrderedAscending;
	}
	return ret;
}

// 複数項目ソートで使用する比較関数
NSInteger stringSort3(id obj1, id obj2, void *context)
{

	NSString *str = [NSString stringWithCString:context encoding:NSUTF8StringEncoding];
	NSArray *arrayColumn =[str componentsSeparatedByString:@","];
	NSMutableArray *arrayResults =[NSMutableArray array];
	NSInteger ret;

	//各列毎に比較結果を求め、結果配列に書き出す
	for(int i=0;i<[arrayColumn count];i=i+2){

		int index = [[arrayColumn objectAtIndex:i] intValue];
		NSString *sign = [arrayColumn objectAtIndex:i+1];
	 	ret = [[obj1 objectAtIndex:index] compare:[obj2 objectAtIndex:index]];

		if ([sign isEqual:@"D"]) {
			if (ret == NSOrderedAscending)
				ret = NSOrderedDescending;
			else if (ret == NSOrderedDescending)
				ret = NSOrderedAscending;
		}

		NSNumber *num = [NSNumber numberWithInt:ret];
		[arrayResults addObject:num];
	}

	//結果配列から判定を求める
	for(int i=0;i<[arrayResults count];i++){
		ret = [[arrayResults objectAtIndex:i]intValue];
		if (ret!=NSOrderedSame) {
			return ret;
		}
	}
	return ret;
}

#import 

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	//init
	NSMutableArray *array1 = [NSMutableArray array];
	NSMutableArray *array = [NSMutableArray array];

	//add
	[array addObject:@"test2"];
	[array addObject:@"test5"];
	[array1 addObject:[array mutableCopy]];
	array = [NSMutableArray array];

	[array addObject:@"test2"];
	[array addObject:@"test4"];
	[array1 addObject:[array mutableCopy]];
	array = [NSMutableArray array];

	[array addObject:@"test3"];
	[array addObject:@"test2"];
	[array1 addObject:[array mutableCopy]];
	array = [NSMutableArray array];

	//value
	NSLog(@"%@",[[array1 objectAtIndex:0] objectAtIndex:0]);
	NSLog(@"%@",[[array1 objectAtIndex:0] objectAtIndex:1]);
	NSLog(@"%@",[[array1 objectAtIndex:1] objectAtIndex:0]);
	NSLog(@"%@",[[array1 objectAtIndex:1] objectAtIndex:1]);
	NSLog(@"%@",[[array1 objectAtIndex:2] objectAtIndex:0]);
	NSLog(@"%@",[[array1 objectAtIndex:2] objectAtIndex:1]);

	//count
	NSLog(@"array count = %d",[array1 count]);

	//1項目sort 昇順
	[array1 sortUsingFunction:stringSort1 context:(void*)0];
	NSLog(@"1項目sort 昇順=%@",array1);
	//1項目sort 降順
	[array1 sortUsingFunction:stringSort1 context:(void*)1];
	NSLog(@"1項目sort 降順=%@",array1);
	//2項目sort 昇順
	[array1 sortUsingFunction:stringSort2 context:(void*)0];
	NSLog(@"2項目sort 昇順=%@",array1);
	//2項目sort 降順
	[array1 sortUsingFunction:stringSort2 context:(void*)1];
	NSLog(@"2項目sort 降順=%@",array1);
	//多項目sort
	[array1 sortUsingFunction:stringSort3 context:(void*)"0,D,1,A"];
	NSLog(@"多項目sort=%@",array1);

	//clear
	for(int i=0;i<[array1 count];i++){
		for (int j=0;j<[[array1 objectAtIndex:i] count];j++){
		 [[[array1 objectAtIndex:i]objectAtIndex:j] release];
		}
	}
	array1 = [NSMutableArray array];
	NSLog(@"array count = %d",[array1 count]);
	NSLog(@"%@",array1);

    [pool drain];
    return 0;
}
◆結果

2011-03-05 10:29:18.822 CollectionTest04[18048:a0f] test2
2011-03-05 10:29:18.826 CollectionTest04[18048:a0f] test5
2011-03-05 10:29:18.827 CollectionTest04[18048:a0f] test2
2011-03-05 10:29:18.829 CollectionTest04[18048:a0f] test4
2011-03-05 10:29:18.829 CollectionTest04[18048:a0f] test3
2011-03-05 10:29:18.830 CollectionTest04[18048:a0f] test2
2011-03-05 10:29:18.831 CollectionTest04[18048:a0f] array count = 3
2011-03-05 10:29:18.832 CollectionTest04[18048:a0f] 1項目sort 昇順=(
        (
        test2,
        test5
    ),
        (
        test2,
        test4
    ),
        (
        test3,
        test2
    )
)
2011-03-05 10:29:18.833 CollectionTest04[18048:a0f] 1項目sort 降順=(
        (
        test3,
        test2
    ),
        (
        test2,
        test5
    ),
        (
        test2,
        test4
    )
)
2011-03-05 10:29:18.835 CollectionTest04[18048:a0f] 2項目sort 昇順=(
        (
        test2,
        test4
    ),
        (
        test2,
        test5
    ),
        (
        test3,
        test2
    )
)
2011-03-05 10:29:18.836 CollectionTest04[18048:a0f] 2項目sort 降順=(
        (
        test3,
        test2
    ),
        (
        test2,
        test5
    ),
        (
        test2,
        test4
    )
)
2011-03-05 10:29:18.837 CollectionTest04[18048:a0f] 多項目sort=(
        (
        test3,
        test2
    ),
        (
        test2,
        test4
    ),
        (
        test2,
        test5
    )
)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です