Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have two functions to split string to array of strings. Input string is: (1Letter E|V|R) + 8 number, last component of string (1Letter + V) + 8 or less numbers.

I'v got two functions advised to use, both of them are working properly. But I can't decide which one is better to use.

1st:

- (NSArray *) componentSaparetedByLength:(NSUInteger) length{
        NSMutableArray *array = [NSMutableArray new];
        NSRange range = NSMakeRange(0, length);
        NSString *subString = nil;
        while (range.location + range.length <= self.length) {
            subString = [self substringWithRange:range];
            [array addObject:subString];
            //Edit
            range.location = range.length + range.location;
            //Edit
            range.length = length;
        }

        if(range.location<self.length){
            subString = [self substringFromIndex:range.location];
            [array addObject:subString];
        }
        return array;
}

2nd:

NSMutableArray *brokenString=[NSMutableArray new];

int start=0;
for (; start<mainString.length-9; start+=9) {
     [brokenString addObject:[mainString substringWithRange:NSMakeRange(start, 9)]];
}
[brokenString addObject:[mainString substringFromIndex:start]];
NSLog(@"->%@",brokenString);
share|improve this question

1 Answer 1

up vote 2 down vote accepted

I would favor the first category approach, as it takes benefit of a great Objective-C feature: extend existing classes with new methods.

On the other hand probably both ways will fail if it comes to more advanced characters, like surrogate pairs, base characters plus combining marks, Hangul jamo, and Indic consonant clusters.

So here is my Category implementation:

@interface NSString (Split)
-(NSArray *)arrayBySplittingWithMaximumSize:(NSUInteger)size;
@end

@implementation NSString (Split)

-(NSArray *)arrayBySplittingWithMaximumSize:(NSUInteger)size
{
    NSMutableArray *letterArray = [NSMutableArray array];
    [self enumerateSubstringsInRange:NSMakeRange(0, [self length])
                                options:(NSStringEnumerationByComposedCharacterSequences)
                             usingBlock:^(NSString *substring,
                                          NSRange substringRange,
                                          NSRange enclosingRange,
                                          BOOL *stop) {
                                 [letterArray addObject:substring];
                             }];


    NSMutableArray *array = [NSMutableArray array];
    [letterArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if (idx%size == 0) {
            [array addObject: [NSMutableString stringWithCapacity:size]];
        }
        NSMutableString *string = [array objectAtIndex:[array count]-1];
        [string appendString:obj];

    }];

    return array;
}

use it like:

NSArray *arraysWith9Letters = [letters arraysBySplittingWithMaximumSize:9];

This approach could be easily extended to split by words, sentences, lines too

@interface NSString (Split)
-(NSArray *)arrayBySplittingWithMaximumSize:(NSUInteger)size
                                     options:(NSStringEnumerationOptions) option;
@end

@implementation NSString (Split)

-(NSArray *)arrayBySplittingWithMaximumSize:(NSUInteger)size
                                     options:(NSStringEnumerationOptions) option
{
    NSMutableArray *letterArray = [NSMutableArray array];
    [self enumerateSubstringsInRange:NSMakeRange(0, [self length])
                                options:(option)
                             usingBlock:^(NSString *substring,
                                          NSRange substringRange,
                                          NSRange enclosingRange,
                                          BOOL *stop) {
                                 [letterArray addObject:substring];
                             }];


    NSMutableArray *array = [NSMutableArray array];
    [letterArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if (idx%size == 0) {
            [array addObject: [NSMutableString stringWithCapacity:size]];
        }
        NSMutableString *string = [array objectAtIndex:[array count]-1];
        [string appendString:obj];

    }];

    return array;
}

Now use it like

NSString *letters = @"ABCDEF𝍱कट्रತ್ಯÖäüℝ𠁙ijgrvਉਤਸੁਕsasas";
NSArray *arraysWith9Letters = [letters arraysBySplittingWithMaximumSize:9 options:NSStringEnumerationByComposedCharacterSequences] ;
NSLog(@"%@", arraysWith9Letters);

NSString *lorem = @"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam";
NSArray *loremArray = [lorem arraysBySplittingWithMaximumSize:9 options:NSStringEnumerationByWords];
NSLog(@"%@", loremArray);
share|improve this answer
    
Thank you for your opinion and your implementation, I will consider accepting after a day, just maybe another answer might occur :). That's a great code you'v written here but for wider usage. But is it worth it to implement it, if i know that i will never get different strings only E|V|R + 8numbers? –  Datenshi Dec 14 '12 at 6:56
    
a category makes it dead simple to re-use code. when it is so simple to write code, that can be used in different situation, why not? –  vikingosegundo Dec 14 '12 at 11:22
    
@vikingosegundo: your method is just awesome. OP's two method cant compete with your block based. I have a doubt between 1 and 2 w.r.t. memory and complexity. How can we find the complexity of both the methods? –  Anoop Vaidya Jan 23 '13 at 7:07
    
@AnoopVaidya — are you talking of BigO? –  vikingosegundo Jan 23 '13 at 19:02
    
@vikingosegundo : Yes –  Anoop Vaidya Jan 23 '13 at 19:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.