使用NSStringCompareOptions

时间:2016-11-18 09:57:36

标签: ios xcode sorting nsstring

我正在尝试排序一些字符串列表。元素的名称几乎可以是任何东西,从真实姓名,字符串,日期,......和数字。

我找到NSStringCompareOptions NSNumericSearch,工作得足够快,而且效果很好:

[1,2,21,3,55,6] --> [1,2,3,6,21,55]

但我的问题是负数

[1,2,3,-1,-4,-5] --> [-1,-4,-5,1,2,3]

什么是不对的。

我知道Apple留下来了:

Numeric comparison only applies to the numerals in the string, 
not other characters that would have meaning in a numeric representation
such as a negative sign, a comma, or a decimal point.

但我的问题是如何实现这一点,因为我知道我不仅仅是这样做的人。

编辑:

感谢Narendra Pandey,但我的真实案例有点复杂,所以他的答案不能在这里使用。

那么就说我有一些字典,数字作为键和字符串作为值:

dic = {@1:@"123", @2:@"-123", @5:"MyName",...};

然后我有一个带有id的对象数组。

array = @[{object with id 5}, {object with id 2},...];

我需要按属性名称排序对象数组。

NSStringCompareOptions comparisonOption = NSCaseInsensitiveSearch | NSNumericSearch;

array = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {

    NSString * name1 = [dic objectForKey:obj1.someId];
    NSString * name2 = [dic objectForKey:obj2.someId];

    return [name1 compare:name2 options:comparisonOption];;
}];

编辑2:

也许我应该声明我有解决方案,但是使用NSStringCompareOptions进行排序的速度要慢4倍

// CHECK IF IT IS NUMBER

NSNumber * number1 = [numberFormatter numberFromString:string1];
NSNumber * number2 = [numberFormatter numberFromString:string2];
//
//    NSLog(@"NUMBERS : %@, %@", number1, number2);
if (number1 && number2) {
    return [number1 compare:number2];
}

return [string1 compare:string2 options:comparisonOption];

3 个答案:

答案 0 :(得分:0)

public partial class MainWindow : INotifyPropertyChanged
{
    private bool _flag1;
    private bool _flag2;

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        Flag1 = true;
        Flag2 = false;
    }
    public bool Flag1 {
        get {
            return _flag1;
        }
        set {
            _flag1 = value;
            OnPropertyChanged();
        }
    }

    public bool Flag2 {
        get {
            return _flag2;
        }
        set {
            _flag2 = value;
            OnPropertyChanged();
        }
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e) {
        Flag1 = !Flag1;
        Flag2 = !Flag2;
    }
}

输出:

NSArray * numbers = @[@1, @2, @3, @-4, @-5, @6, @9];

    NSPredicate * predicateForPositive = [NSPredicate predicateWithFormat:@"integerValue >= 0"];

    NSArray * positiveNumbers = [numbers filteredArrayUsingPredicate:predicateForPositive];

    NSPredicate * predicateForNegative = [NSPredicate predicateWithFormat:@"integerValue <= 0"];

    NSArray * NegativeNumber = [numbers filteredArrayUsingPredicate:predicateForNegative];


    NSLog(@"Negative  number %@",NegativeNumber);

    NSLog(@"Positive number %@",positiveNumbers);

现在对两者进行排序并连接两个数组。

答案 1 :(得分:0)

感谢Narendra Pandey,我为我找到了解决方案。

首先让我说Narendra Pandey解决方案有效,但它更慢,甚至3次。
(在我的情况下,使用NSStringCompareOptions 0.014s,以及0,042 Narendra Pandey解决方案)。

但如果我使用他的想法并稍微改变一下:

array = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {


    NSString * name1 = somehow get string1;
    NSString * name2 = somehow get string2;

    if ([string1 integerValue] <0 && [string2 integerValue]<0) {
        return - [string1 compare:string2 options:comparisonOption];
    }

    return [string1 compare:string2 options:comparisonOption];

}];

这种方法更快,在我的情况下为0,015s,与NSStringCompareOptions相当。

通过这种方式,您可以避免在开始时通过整个数组来分隔负数和正数,然后对它们进行排序。

答案 2 :(得分:0)

此函数获取 any 数组并将其转换为排序的 Double 数组

var numberArray: [Any] = [4, 3.9, -23,3, 7.6, -51, 75.3, "0", "-(22)"]

/// This function get any array and convert it to sorted _Double_ array
/// - Note: Non-numerical elements are automatically removed from the array
/// - Parameters:
///     - numbers: array of anything
/// - Returns: sorted _Double_ array
func sortAnyNumbers(_ numbers: [Any]) -> [Double] {
    var _numbers: [Double] = []
    numbers.forEach { number in
        // Delete non-numeric characters
        if let numb = Double("\(number)".components(separatedBy: CharacterSet(charactersIn: "-01234567890.").inverted).joined()) {
            _numbers.append(numb)
        }
    }
    return _numbers.sorted()
}

print(sortAnyNumbers(numberArray))  //[-51.0, -23.0, -22.0, 0.0, 3.0, 3.9, 4.0, 7.6, 75.3]