NSArrayをFinder風の並び順でソートする

こんなファイルがあったとする。

file-a
file-1
file-01
file-2
file-10
file-b
file-ab

辞書式(普通の昇順ソート)で並べ替えると

file-01
file-1
file-10
file-2
file-a
file-ab
file-b

となるわけだが、Finderでソートすると

file-1
file-01
file-2
file-10
file-a
file-ab
file-b

となる。連続した数字部分を数値と見なし、数値順で並べてくれる。個人的にはこの方が分かりやすくて好きだ。

で、この数値順ソートをCocoaで実現するにはどーしたらいいのかなー?と思って調べていたら、Technical Q&A QA1159: Sorting Like the Finderという、そのまんまの記事がADCにあった。流石林檎様、分かっていらっしゃる。

上記Q&Aのコードを改造してNSMutableArrayのカテゴリメソッドにするとスマートに使えて良い感じ。

NSString配列のソートはもちろん、任意のオブジェクトの場合はソートに使うNSStringインスタンス変数名をsortByFinderOrderWithStringObjectKey:に渡せばおk。

#include <CoreServices/CoreServices.h>
#include <sys/param.h>
 
static CFComparisonResult CompareLikeTheFinder(const void *val1, const void *val2, void *context)
{
    SInt32          compareResult;
    CFStringRef     lhsStr;
    CFStringRef     rhsStr;
    CFIndex         lhsLen;
    CFIndex         rhsLen;
    UniChar         lhsBuf[MAXPATHLEN];
    UniChar         rhsBuf[MAXPATHLEN];
 
    // val1 is the left-hand side CFString.
    // val2 is the right-hand side CFString.
    if (context)
    {
        NSString *key = (NSString *)context;
        lhsStr = (CFStringRef)[(NSObject *)val1 valueForKey:key];
        rhsStr = (CFStringRef)[(NSObject *)val2 valueForKey:key];
    }
    else
    {
        lhsStr = (CFStringRef)val1;
        rhsStr = (CFStringRef)val2;
    }
    lhsLen = CFStringGetLength(lhsStr);
    rhsLen = CFStringGetLength(rhsStr);
 
    // Get the actual Unicode characters (UTF-16) for each string.
    CFStringGetCharacters(lhsStr, CFRangeMake(0, lhsLen), lhsBuf);
    CFStringGetCharacters(rhsStr, CFRangeMake(0, rhsLen), rhsBuf);
 
    // Do the comparison.
    UCCompareTextDefault(
                         kUCCollateComposeInsensitiveMask
                         | kUCCollateWidthInsensitiveMask
                         | kUCCollateCaseInsensitiveMask
                         | kUCCollateDigitsOverrideMask
                         | kUCCollateDigitsAsNumberMask
                         | kUCCollatePunctuationSignificantMask,
                         lhsBuf,
                         lhsLen,
                         rhsBuf,
                         rhsLen,
                         NULL,
                         &compareResult
                         );
 
    // Return the result. Conveniently, UCCompareTextDefault 
    // returns -1, 0, or +1, which matches the values for 
    // CFComparisonResult exactly.
    return (CFComparisonResult)compareResult;
}
 
static void SortCFMutableArrayLikeTheFinder(CFMutableArrayRef array, CFStringRef key)
{
    CFArraySortValues(
                      array, 
                      CFRangeMake(0, CFArrayGetCount(array)),
                      CompareLikeTheFinder,
                      key
                      );
}
 
@interface NSMutableArray (PKAdditions)
- (void)sortByFinderOrder;
- (void)sortByFinderOrderWithStringObjectKey:(NSString *)key;
@end
 
@implementation NSMutableArray (PKAdditions)
- (void)sortByFinderOrder
{
    [self sortByFinderOrderWithStringObjectKey:nil];
}
 
- (void)sortByFinderOrderWithStringObjectKey:(NSString *)key
{
    SortCFMutableArrayLikeTheFinder(self, key);
}
@end

実際のファイル名やディレクトリ名をソートする場合は、- [NSFileManager displayNameAtPath:(NSString *)path]で得られる名前をソートしないとFinder順にはならない。なぜかというと、Finderから見えるディレクトリ名はローカライズ(~/Documents → 書類 みたいなの)された物なので。

купоны на скидку кфс 2022 яндекс лавка промокод на скидку купон брендшоп на скидку прогон по профилям трастовых сайтов

бургер скидки купоны боулинг купоны на скидку http://best-realtors.com.ua/index.php?subaction=userinfo&user=gaudyunderdog17 casino бездепозитный бонус промокоды http://dubizzle.ca/index.php?page=item&id=22143 бесплатный автоматический прогон по каталогам сайтов https://gidro2000.com/forum-gidro/user/38470/

промокод на скидку sunlight https://karabast.com/wiki/index.php/%D0%9F%D1%80%D0%BE%D0%B4%D0%B2%D0%B8%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D1%81%D0%B0%D0%B9%D1%82%D0%B0_%D0%B2_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%BE%D0%B2%D1%8B%D1%85_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0%D1%85_%D1%81%D0%BA%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE_%D1%81%D1%82%D0%BE%D0%B8%D1%82 скачать фильм лет бесплатно на телефон http://c.daum7.net/bbs/board.php?bo_table=free&wr_id=2848651 город промокод на скидку http://axiomaj.ru/index.php?subaction=userinfo&user=organicgas18 промокод на скидку такси

индексация страниц яндексом https://staging.arabunityschool.ae/cryptoboss-casino-%D0%BA%D0%B0%D0%BA-%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C-%D0%BC%D0%B0%D0%BA%D1%81%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9-%D0%B1%D0%BE%D0%BD%D1%83%D1%81-%D0%BF/ программы для прогона сайтов бездепозитный бонус в покер https://www.sissipedia.wiki/index.php?title=User:Rae702035265891 проверка сайта на индексацию онлайн

прогон сайта по белым каталогам что это прогон по базе сайтов http://chansolburn.com/bbs/board.php?bo_table=free&wr_id=1366220 продвижение в маркетинге статья http://xn--b1acebaenad0ccc3aiee.xn--p1ai/forum/user/28883/ фудзияма купон на скидку 2022

скидки промокоды на технику https://lolipop-pandahouse.ssl-lolipop.jp:443/g5/bbs/board.php?bo_table=aaa&wr_id=2268578 деливери клаб промокод на скидку http://bazarweb.ru/forum.php?PAGE_NAME=profile_view&UID=43887 промокод озон на скидку от 2500 http://bwiki.dirkmeyer.info/index.php?title=%D0%9F%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0_%D0%A2%D0%B5%D1%85%D0%BD%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%9F%D0%B5%D1%80%D0%B5%D0%BE%D0%B1%D1%85%D0%BE%D0%B4_%D0%A1%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86_%D0%A1%D0%B0%D0%B9%D1%82%D0%B0 как прогон сайта по трастовым профилям

индексация ссылок сервис сайт прогонов фильмы 2021 скачать бесплатно на телефон хорошем http://receptom.ru/index.php?subaction=userinfo&user=jitteryentrails статьи создание продвижение сайтов http://www.pk10zc.com/space-uid-408344.html

какой лучше прогон для сайта https://sunbrand.co.kr/bbs/board.php?bo_table=free&wr_id=1018586 ржд промокод на скидку 2022 https://pediascape.science/wiki/%D0%92%D0%B8%D0%B4%D0%B5%D0%BE_%D0%BA%D0%B0%D0%BA%D0%BE%D0%B3%D0%BE_%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B0_%D0%BA%D0%B0%D1%87%D0%B0%D1%82%D1%8C_%D1%82%D0%BE%D1%80%D1%80%D0%B5%D0%BD%D1%82 купон на скидку ижавиа http://ips-irk.ksworks.ru/index.php?subaction=userinfo&user=purplebruise83 прогон по базе трастовым сайтов https://bvt.by/forum/user/4453/ индексирование сайтов роботами

1 | | 2026-04-07 05:24 | reply



  • blog/2013/2013-02-16.txt
  • 最終更新: 2015-01-06 11:51
  • (外部編集)