Objective c 创建一个以逗号分隔的列表,并使用“quot;及;尤其是在目标C中的最后一项之前

Objective c 创建一个以逗号分隔的列表,并使用“quot;及;尤其是在目标C中的最后一项之前,objective-c,arrays,string,cocoa,human-readable,Objective C,Arrays,String,Cocoa,Human Readable,我想写一个方法,提供一个可读的数组字符串表示,必要时使用逗号空格(包括牛津逗号),并在末尾加上一个连环的“and” 例如,假设我有以下数组: NSArray *nun = @[]; NSArray *won = @[@"The Loneliest"]; NSArray *too = @[@"Peas", @"Pod"]; NSArray *tree = @[@"Apple", @"Falls", @"Far, Far Away"]; 我想写一个方法,比如: + (NSString*) huma

我想写一个方法,提供一个可读的数组字符串表示,必要时使用逗号空格(包括牛津逗号),并在末尾加上一个连环的“and”

例如,假设我有以下数组:

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"
请注意,第一个项目正好有一个项目,它只是第一个没有装饰的项目。第二个,正好有两个项目,没有逗号,但有连词“and”。第三个项目的超过2个项目,在每个项目之间包含一个逗号空格,最后一个项目在逗号空格之后和项目之前包含一个附加的

在Objective C中有没有一个简单的方法可以做到这一点呢?我在Java等语言中做过这一点,但我知道Objective C的一些方法,如
-(NSString*)[NSArray componentsjoinedbythring:][/code>,可能有助于做到这一点


此问题未由回答,因为它不处理最后一个数组项中的逗号。我也研究过这样的问题,他们没有提到人类可读性的这一良好部分。

正是您所需要的

以下是该项目自述文件中的示例

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"

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];
}
未测试:

+ (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]];
}

以下是如何在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"

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

扩展数组,其中Iterator.Element==String{ func与逗号连接(useOxfordComma:Bool=false,maxItemCount:Int=-1)->String{ 让结果:字符串 如果maxItemCount>=0&&count>maxItemCount{ 结果=自身[0..=2,则为else{ 让lastIndex=count-1 让extraComma=(useOxfordComma&&count>2)?,:“ 结果=self[0..
duplicate of:创建逗号分隔列表,然后按照此链接替换最后一个逗号。如果最后一项中有逗号,这就不起作用了。请参阅我的编辑以获得解释。在Objective-C中没有“捷径”可以做到这一点。您需要编写一个for循环,并在需要时添加“and”。用你尝试过的内容更新你的问题。打败我。:)你所需要的只是一个开关,用于判断>=3的大小写是否使用牛津逗号。请查看编辑是否符合您的意思。很好。斯特伦克和怀特会感到骄傲的。或者至少可能。这看起来很棒!不幸的是,这是一个企业应用程序,因此添加一个库要经历很多繁文缛节;我怀疑他们会让我只用这一次。不过,在我的个人项目中,我肯定会记住它!当最后一个列表项中有逗号时,此功能将崩溃。像
[“(1,2)”,“(0,0)”,“(5,4)”]
。这会错误地输出
“(1,2)、(0,0)、(5和4)”
这是一个非常幼稚的算法。如果你有时间,请改进它。伟大的解决方案!当你可以使用选项UInt时,为什么要用Int来表示所有的否定呢?@BenLeggiero你的意思是“可选”而不是“选项”?当然,这会起作用,并且可以删除>=0的检查,但是我还有一个额外的if-let语句(或者一个非nil检查和两个force-unwrapps)。从技术上讲,我可能应该使用一个防止maxItemCount小于3的方法,因为在前面没有至少两个项的情况下使用“etc”(英语)是没有意义的,但这给调用者带来了更大的负担,他们必须记住maxItemCount的有效范围。@BenLeggiero对我来说,-1在这种情况下有着感性的数学意义(无可否认,这是一种迂回的方式,而且只对程序员而言)-1是0xFFFFF。。。(F的数量取决于整数大小),因此具有与UInt.max等效的位模式,该位模式尽可能接近范围内的无穷大(无穷大是试图表达的)。事实上,在我看来,它比UInt.max本身更好,因为UInt.max不是无限的,并且不清楚它在语义上是否意味着使用“etc”。只有当计数达到那么高的时候,或者永远不使用“etc.”。是的,对不起;自动更正决定“选项”是一个更好的词:首先,你的答案很好+1.它遵循经过时间测试的实践,并利用了诸如默认参数值和不变性等强大的Swift特性。我只是想知道你对你的方法的看法。
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
    }
}