【问题标题】:Sort negative number string in iOS with NSStringCompareOptions使用 NSStringCompareOptions 对 iOS 中的负数字符串进行排序
【发布时间】:2016-11-18 09:57:36
【问题描述】:

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

我发现NSStringCompareOptionsNSNumericSearch,工作速度足够快,而且效果很好,所以:

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

但我的问题是负数

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

哪里不对。

我知道苹果会留下来:

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];

【问题讨论】:

  • 将负数从该数组分离并存储到另一个数组并转换为正数。然后对该数组进行排序并反转它。现在转换为负数并将其连接到旧数组的顶部。
  • 负数排序有什么问题?期望的输出是什么?

标签: ios xcode sorting nsstring


【解决方案1】:
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);

输出:

Negative  number (
    "-4",
    "-5"
)

Positive number (
    1,
    2,
    3,
    6,
    9
)

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

【讨论】:

  • 感谢您的回答。数字是正确的,但正如我所提到的,我有字符串,而不是数字。第二件事,我没有真正的字符串数组,但是对象,...检查我的更新,...
  • 即使你有字符串也可以。为对象工作:)
【解决方案2】:

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

首先让我声明,Narendra Pandey 解决方案有效,但速度较慢,甚至慢了 3 倍。
(在我的例子中,NSStringCompareOptions 为 0.014 秒,Narendra Pandey 解决方案为 0,042)。

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

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 相当。

这样可以避免一开始就遍历整个数组来区分负数和正数,然后对它们进行排序。

【讨论】:

    【解决方案3】:

    此函数获取任意数组并将其转换为已排序的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]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-30
      • 1970-01-01
      • 2013-04-11
      • 2019-01-13
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      • 2012-11-14
      相关资源
      最近更新 更多