如何将NSNumber数组中的连续数字分组为指定格式的NSString?
实现NSNumber数组转指定格式NSString的方案
嘿,这个问题我之前也遇到过!你已经走对了关键的第一步——排序数组并判断元素连续性,剩下的就是把分组逻辑和字符串拼接的细节处理到位。下面是完整的实现思路和代码示例:
核心步骤拆解
- 排序数组:先把无序的NSNumber数组按数值从小到大排序,这是判断连续性的基础。
- 分组连续序列:遍历排序后的数组,把连续递增1的元素归为一组,非连续的元素开启新组。
- 组转字符串:单个元素的组直接转成数字字符串;多个元素的组用「起始值-结束值」的格式。
- 拼接最终字符串:前面的组用逗号分隔,最后两个组用「 & 」连接,符合你要的格式。
Objective-C 实现代码
NSArray *numberArray = @[@11, @12, @13, @24, @10, @25, @26, @41, @30]; // 1. 对NSNumber数组排序 NSArray *sortedArray = [numberArray sortedArrayUsingComparator:^NSComparisonResult(NSNumber *obj1, NSNumber *obj2) { return [obj1 compare:obj2]; }]; // 2. 分组连续元素 NSMutableArray *groups = [NSMutableArray array]; NSMutableArray *currentGroup = [NSMutableArray arrayWithObject:sortedArray.firstObject]; for (NSInteger i = 1; i < sortedArray.count; i++) { NSNumber *prevNum = sortedArray[i-1]; NSNumber *currentNum = sortedArray[i]; // 判断当前元素是否和前一个连续(差值为1) if ([currentNum integerValue] == [prevNum integerValue] + 1) { [currentGroup addObject:currentNum]; } else { // 非连续则保存当前组,开启新组 [groups addObject:[currentGroup copy]]; currentGroup = [NSMutableArray arrayWithObject:currentNum]; } } // 别忘了把最后一组加入分组列表 [groups addObject:currentGroup]; // 3. 将每组转换为对应格式的字符串 NSMutableArray *groupStrings = [NSMutableArray array]; for (NSArray *group in groups) { if (group.count == 1) { [groupStrings addObject:[group.firstObject stringValue]]; } else { NSString *rangeStr = [NSString stringWithFormat:@"%@-%@", group.firstObject, group.lastObject]; [groupStrings addObject:rangeStr]; } } // 4. 拼接最终结果,处理最后一组的&连接 NSString *result; if (groupStrings.count == 1) { result = groupStrings.firstObject; } else { // 取前n-1个组用逗号拼接,再和最后一组用&连接 NSArray *allButLastGroups = [groupStrings subarrayWithRange:NSMakeRange(0, groupStrings.count - 1)]; NSString *prefix = [allButLastGroups componentsJoinedByString:@", "]; result = [NSString stringWithFormat:@"%@ & %@", prefix, groupStrings.lastObject]; } NSLog(@"%@", result); // 输出:10-13, 24-26, 30 & 41
Swift 实现代码(如果需要)
let numberArray: [NSNumber] = [11, 12, 13, 24, 10, 25, 26, 41, 30] // 转成Int数组并排序 let sortedNumbers = numberArray.map { $0.intValue }.sorted() // 分组连续元素 var groups: [[Int]] = [] var currentGroup = [sortedNumbers.first!] for i in 1..<sortedNumbers.count { let prev = sortedNumbers[i-1] let current = sortedNumbers[i] if current == prev + 1 { currentGroup.append(current) } else { groups.append(currentGroup) currentGroup = [current] } } groups.append(currentGroup) // 组转字符串 let groupStrings = groups.map { group in group.count == 1 ? "\(group.first!)" : "\(group.first!)-\(group.last!)" } // 拼接最终结果 let result: String if groupStrings.count == 1 { result = groupStrings.first! } else { let prefix = groupStrings.dropLast().joined(separator: ", ") result = "\(prefix) & \(groupStrings.last!)" } print(result) // 输出:10-13, 24-26, 30 & 41
关键细节说明
- 不要遗漏最后一组:遍历结束后必须把
currentGroup加入分组列表,否则会丢失最后一组元素。 - 边界情况处理:如果数组只有一个元素,直接返回该元素的字符串即可,避免拼接逻辑出错。
- 格式严格匹配:最后两个组用「 & 」连接,前面的组用「, 」分隔,完全符合你要的输出格式。
内容的提问来源于stack exchange,提问作者malaki1974
相关产品推荐
相关产品推荐

