0

我想编写一种方法,该方法提供数组的人类可读字符串表示,必要时使用逗号空格(包括牛津逗号),并在末尾连接“和”。

例如,假设我有这些数组:

NSArray *nun = @[];
NSArray *won = @[@"The Loneliest"];
NSArray *too = @[@"Peas", @"Pod"];
NSArray *tree = @[@"Apple", @"Falls", @"Far, Far Away"];

我想写一个方法,如:

+ (NSString*) humanReadableListFromArray: (NSArray*) arr
{
  // magic
}

当我通过我的数组时,我希望它们看起来像这样:

@""
@"The Loneliest"
@"Peas and Pod"
@"Apple, Falls, and Far, Far Away"

请注意,第一个只有 1 个 item,它只是第一个没有装饰的 item。第二个,正好有 2 个项目,没有逗号,但有连接的“和”。第三个,有超过 2 个项目,在每个项目之间包含一个逗号空格,最后一个项目and在逗号空格之后和项目之前包含一个附加项。

在Objective C中是否有一种简短的方法可以做到这一点?我已经用 Java 等语言完成了这项工作,但我知道 Objective C 具有类似-(NSString*)[NSArray componentsJoinedByString:]的方法可能会对此有所帮助。


用“and”替换字符串中的最后一个逗号没有回答这个问题。(Objective-C)因为它不处理最后一个数组项中的逗号。我还研究了诸如Objective-C Simplest way to create comma separator string from a array of objects 之类的问题,他们没有提到人类可读性的这一好部分。

4

5 回答 5

6

@timgcarlson 提到的第三方库听起来很有希望。这就是我在本地做的事情......

- (NSString *)humanReadableListFromArray:(NSArray *)array withOxfordStyle:(BOOL)oxford {
    if (array.count == 0) return @"";
    if (array.count == 1) return array[0];
    if (array.count == 2) return [array componentsJoinedByString:@" and "];

    NSArray *firstItems = [array subarrayWithRange:NSMakeRange(0, array.count-1)];
    NSString *lastItem = [array lastObject];
    NSString *lastDelimiter = (oxford)? @", and " : @" and ";
    return [NSString stringWithFormat:@"%@%@%@",
        [firstItems componentsJoinedByString:@", "], lastDelimiter, lastItem];
}
于 2015-07-08T18:40:46.483 回答
3

TTTFormatterKit正是您所需要的。

这是项目自述文件中的示例...

NSArray *list = [NSArray arrayWithObjects:@"Russel", @"Spinoza", @"Rawls", nil];
TTTArrayFormatter *arrayFormatter = [[TTTArrayFormatter alloc] init];
[arrayFormatter setUsesSerialDelimiter:NO]; // Omit Oxford Comma
NSLog(@"%@", [arrayFormatter stringFromArray:list]); // "Russell, Spinoza and Rawls"
于 2015-07-08T18:35:34.397 回答
1

未测试:

+ (NSString*)humanReadableListFromArray:(NSArray*) arr
{
   NSUInteger count = [arr count];
   if (count == 0)
        return @"";
   else if (count == 1)
        return arr[0];

   NSString *subarrayStr;
   if (count == 2) {
       subarrayStr = arr[0];
   } else {
       NSArray *subarray = [arr subarrayWithRange:NSMakeRange(0, count - 1)];
       subarrayStr = [subarray componentsJoinedByString:@", "];
   }

   return [[subarrayStr stringByAppendingString:@" and "] stringByAppendingString:arr[count - 1]];
}
于 2015-07-08T18:42:12.160 回答
1

以下是在 Swift 3 中的操作方法:

extension Collection where Iterator.Element == String {
    func joinedWithComma() -> String {
        var string = joined(separator: ", ")

        if let lastCommaRange = string.range(of: ", ", options: .backwards) {
            string.replaceSubrange(lastCommaRange, with: " and ")
        }

        return string
    }
}

["A", "B", "C"].joinedWithComma() // returns "A, B and C"
于 2017-02-06T10:51:14.890 回答
1

这是 Swift 4 版本。它支持项目内的逗号、牛津逗号的可选使用和最大项目数。如果元素的数量高于 maxItemCount 它会缩短列表并将等添加到列表的末尾。注意:假设此函数用于在句子末尾添加列表,因此“等”后没有标点符号,否则您最终会得到 2 个句点,例如“我喜欢很多水果:苹果、梨、草莓, ETC..”

extension Array where Iterator.Element == String {
    func joinedWithComma(useOxfordComma: Bool = false, maxItemCount: Int = -1) -> String {
        let result: String
        if maxItemCount >= 0 && count > maxItemCount {
            result = self[0 ..< maxItemCount].joined(separator: ", ") + ", etc"
        } else if count >= 2 {
            let lastIndex = count - 1
            let extraComma = (useOxfordComma && count > 2) ? "," : ""
            result = self[0 ..< lastIndex].joined(separator: ", ") + extraComma + " and " + self[lastIndex]
        } else if count == 1 {
            result = self[0]
        } else {
            result = ""
        }

        return result
    }
}
于 2018-09-10T23:04:24.767 回答