在objectiveC中对具有特殊字符,数字,英语和阿拉伯字符串的数组进行排序

时间:2015-10-07 08:15:49

标签: objective-c sorting special-characters multilingual nssortdescriptor

我正在开发一个在objectiveC中的iPhone应用程序,其中我有一个包含字母数字,多语言,特殊字符数据的数组,如下所示:

(
    {
        name = “#”;
    },
    {
        name = “iPad”;
    },
    {
        name = “عينة”;
    },
    {
        name = “1”;
    },
    {
        name = “أ”;
    },
    {
        name = “10”;
    },

)

排序应该为我提供如下结果,

(
    {
        name = “iPad”;
    },
    {
        name = “أ”;
    },
    {
        name = “عينة”;
    }
    {
        name = “#”;
    },
    {
        name = “1”;
    },
    {
        name = “10”;
    },

)

首先表示英语和阿拉伯语应按字母顺序升序,然后按特殊字符,然后按升序排列。

2 个答案:

答案 0 :(得分:0)

我使用正则表达式得到了解决方案,如下所示

   NSMutableArray *aMutArrArabic = [[NSMutableArray alloc] init];
   for(NSDictionary *aDictObj in mutArrAddCard)
   {
        NSError *error = NULL;
        NSRegularExpression *aRegexObj = [NSRegularExpression regularExpressionWithPattern:@"^[ء-ي]+$"
                                                                                       options:NSRegularExpressionCaseInsensitive
                                                                                         error:&error];
        NSArray *aArrMatches = [aRegexObj matchesInString:aDictObj[@"name"]
                                                  options:0
                                                    range:NSMakeRange(0, [aDictObj[@"name"] length])];

        if([aArrMatches count] > 0)
        {
           [aMutArrArabic addObject:aDictObj];
        }
   }

这样我就可以使用相关的正则表达式来获取所有数组。

答案 1 :(得分:0)

可能会有一些改进,这可以通过sortedArrayUsingComparator:和自定义比较器块来实现。

主要思想:
  - 获取字符串的第一个字符   - 确定它的“种类”(字母,阿拉伯语,数字,其他)
  - 相应地排序。

我从这些“善意”开始:

typedef enum : NSUInteger {
    CharacterOfKindArabic,
    CharacterOfKindNumerical,
    CharacterOfKindLetter,
    CharacterOfKindOther
} CharacterOfKind;

并使用此方法获取CharacterOfKind:

-(CharacterOfKind)retrieveFirstCharacterKindFromString:(NSString *)string
{
    if ([string length])
    {
        unichar unicharacter = [string characterAtIndex:0];
        if (unicharacter >= 0x600 && unicharacter <= 0x6ff)
            return CharacterOfKindArabic;
        if (unicharacter >= 0x750 && unicharacter <= 0x77f)
            return CharacterOfKindArabic;
        if (unicharacter >= 0xfb50 && unicharacter <= 0xfc3f)
            return CharacterOfKindArabic;
        if (unicharacter >= 0xfe70 && unicharacter <= 0xfefc)
            return CharacterOfKindArabic;

        NSString *firstChar = [string substringToIndex:1];
        if ([firstChar rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet] options:0].location != NSNotFound)
            return CharacterOfKindNumerical;
        if ([firstChar rangeOfCharacterFromSet:[NSCharacterSet letterCharacterSet] options:0].location != NSNotFound)
            return CharacterOfKindLetter;
        return CharacterOfKindOther;
    }
    return CharacterOfKindOther;
}

我不会说阿拉伯语,我从来没有用阿拉伯语文本编码。所以我从网上获取了“角色范围”的这些信息。我在StackOverflow上阅读了有关Objective-C的内容,但我无法检索它。也许我的记忆正在和我一起玩,但范围可能已经改变(增加了更多范围)。我觉得这个方法有点难看,但那是为了得到主要观点。

NSString *kName = @"name";
NSArray *arrayToSort = @[@{kName:@"#"},
                         @{kName:@"iPhone"},
                         @{kName:@"iPad"},
                         @{kName:@"عينة"},
                         @{kName:@"1"},
                         @{kName:@"أ"},
                         @{kName:@"10"}];

NSLog(@"arrayToSort: %@", arrayToSort);

NSArray *typeSort = @[@(CharacterOfKindLetter), @(CharacterOfKindArabic), @(CharacterOfKindOther), @(CharacterOfKindNumerical)];
NSArray *sortedArray = [arrayToSort sortedArrayUsingComparator:^NSComparisonResult(NSDictionary * _Nonnull obj1, NSDictionary * _Nonnull obj2)
{
    NSString *firstString = obj1[kName];
    NSString *secondString = obj2[kName];
    CharacterOfKind firstCharType = [self retrieveFirstCharacterKindFromString:firstString];
    CharacterOfKind secondCharType = [self retrieveFirstCharacterKindFromString:secondString];

    if (firstCharType == secondCharType) //Same Kind of first characters, do a normal "compare"
    {
        return [firstString compare:secondString];
    }
    else //Do a custom compare according typeSort
    {
        //Returns correctly according to the order set in typeSort
        return [@([typeSort indexOfObject:@(firstCharType)]) compare:@([typeSort indexOfObject:@(secondCharType)])];
    }
}];

NSLog(@"SortedArray: %@", sortedArray);

输出:

>>>arrayToSort: (
        {
        name = "#";
    },
        {
        name = iPhone;
    },
        {
        name = iPad;
    },
        {
        name = "\U0639\U064a\U0646\U0629";
    },
        {
        name = 1;
    },
        {
        name = "\U0623";
    },
        {
        name = 10;
    }
)
>>>SortedArray: (
        {
        name = iPad;
    },
        {
        name = iPhone;
    },
        {
        name = "\U0623";
    },
        {
        name = "\U0639\U064a\U0646\U0629";
    },
        {
        name = "#";
    },
        {
        name = 1;
    },
        {
        name = 10;
    }
)