ios -[NSArray componentsJoinedByString] with condition

I want to use -[NSArray componentsJoinedByString] with some condition for example : concatenate all elements of my array with ", " except the last one where I want an " and ".

It python it would be something like :

', '.join(array[:-1]) + ' and ' + array[-1]

Is there a way or a method that would do the trick in one line, avoiding all the if else stuff ?


You can use subarrayWithRange: and stringWithFormat: to do the same thing. You do need at least 1 if to check the count of items in the array and ensure that you don't have an index exception.

try like this,i dont know is this effiecient or not but check once,

 NSArray *arr= [[NSArray alloc]initWithObjects:@"1",@"2",@"3", nil];
    NSString *string = [arr componentsJoinedByString:@","];
    NSString *str= [NSString stringWithFormat:@"%@ and %@",[string substringToIndex:[string length]-[[arr lastObject] length]-1],[arr lastObject]];

It might not be the most efficient, but it is a nice simple solution to take an array of objects that have string representations and turn them into a comma separated list such as 1, 2, 3, and 4.

@implementation NSArray (MyCollection)

- (NSString *)stringCommaAndSeparated
    return [self stringCommaAndSeparatedUsingStringConverter:^NSString *(id object) {
        assert( [object isKindOfClass:NSString.class] );
        return (NSString *)object;

- (NSString *)stringCommaAndSeparatedUsingStringConverter:(NSString *(^)(id object))stringConverter
    assert( stringConverter );

    if( self.count == 0 )
        return @"";

    if( self.count == 1 )
        return stringConverter(self.firstObject);

    if( self.count == 2 )
        return [NSString stringWithFormat:NSLocalizedString(@"%@ and %@", nil), stringConverter(self[0]), stringConverter(self[1]) ];

    NSMutableString *string = [[NSMutableString alloc] init];
    for( int index = 0;  index < self.count-1;  index += 1 )
        [string appendFormat:NSLocalizedString(@"%@, ", nil), stringConverter(self[index])];

    [string appendFormat:NSLocalizedString(@"and %@", nil), stringConverter(self.lastObject)];

    return string;  // This is returning a mutable string, but we could copy it to an immutable one!


Here is an example of this in action:

        // Results in @"1, 2, 3, and 4"
        NSString *str  = [@[@"1", @"2", @"3", @"4"] stringCommaAndSeparated];

        // Results in @"1, 2, 3, and 4"
        NSString *str2 = [@[@(1), @(2), @(3), @(4)] stringCommaAndSeparatedUsingStringConverter:^NSString *(id object) {
                assert( [object isKindOfClass:NSNumber.class] );
                NSNumber *number = object;
                return number.stringValue;

Here's my category solution, based on Wain's answer:

@implementation NSArray (NSString)

- (NSString *)listStringUsingLocale:(NSLocale *)locale
        return nil;

        locale = [NSLocale currentLocale];

    NSString *language = [locale objectForKey: NSLocaleLanguageCode];

    if([language isEqualToString:@"en"])
        if (self.count > 1)
            NSArray *arr1 = [self subarrayWithRange:NSMakeRange(0, self.count - 1)];
            return [NSString stringWithFormat:@"%@ and %@", [arr1 componentsJoinedByString:@", "], self.lastObject];
            return self[0];

    return nil;


I've added the option to add locale-based options.

Need Your Help

iOS how to upgrade the last compatible version

ios iphone app-store itunes

Apple offers the user the option to download an older version of the app that is compatible with the device. if device OS is not compatible with latest version of application. Apple is now displayi...