Создать NSString, повторяя другую строку заданное количество раз


это должно быть легко, но мне трудно найти самое простое решение.

мне нужно NSString что равно другой строке, сцепленной с собой заданное число раз.

для лучшего объяснения, рассмотрим следующий пример:

>> original = "abc"
"abc"
>> times = 2
2
>> result = original * times
"abcabc"

какие-то намеки?


EDIT:

Я собирался опубликовать решение, похожее на ответ Майка Макмастера, посмотрев на эту реализацию из OmniFrameworks:

// returns a string consisting of 'aLenght' spaces
+ (NSString *)spacesOfLength:(unsigned int)aLength;
{
static NSMutableString *spaces = nil;
static NSLock *spacesLock;
static unsigned int spacesLength;

if (!spaces) {
spaces = [@"                " mutableCopy];
spacesLength = [spaces length];
    spacesLock = [[NSLock alloc] init];
}
if (spacesLength < aLength) {
    [spacesLock lock];
    while (spacesLength < aLength) {
        [spaces appendString:spaces];
        spacesLength += spacesLength;
    }
    [spacesLock unlock];
}
return [spaces substringToIndex:aLength];
}

код, воспроизведенный из файла:

Frameworks/OmniFoundation/OpenStepExtensions.subproj/NSString-OFExtensions.m

на фреймворке OpenExtensions из Omni Framework by Группа Omni.

5 55

5 ответов:

есть метод под названием stringByPaddingToLength:withString:startingAtIndex::

[@"" stringByPaddingToLength:100 withString: @"abc" startingAtIndex:0]

обратите внимание, что если вы хотите 3 abc, чем использовать 9 (3 * [@"abc" length]) или создать Категорию, как это:

@interface NSString (Repeat)

- (NSString *)repeatTimes:(NSUInteger)times;

@end

@implementation NSString (Repeat)

- (NSString *)repeatTimes:(NSUInteger)times {
  return [@"" stringByPaddingToLength:times * [self length] withString:self startingAtIndex:0];
}

@end
NSString *original = @"abc";
int times = 2;

// Capacity does not limit the length, it's just an initial capacity
NSMutableString *result = [NSMutableString stringWithCapacity:[original length] * times]; 

int i;
for (i = 0; i < times; i++)
    [result appendString:original];

NSLog(@"result: %@", result); // prints "abcabc"

для производительности вы можете перейти на C с чем-то вроде этого:

+ (NSString*)stringWithRepeatCharacter:(char)character times:(unsigned int)repetitions;
{
    char repeatString[repetitions + 1];
    memset(repeatString, character, repetitions);

    // Set terminating null
    repeatString[repetitions] = 0;

    return [NSString stringWithCString:repeatString];
}

Это может быть записано как расширение категории в классе NSString. Вероятно, есть некоторые проверки, которые должны быть брошены туда, но это прямая суть этого.

первый метод выше для одного символа. Это строка символов. Он также может использоваться для одного символа, но имеет больше накладных расходов.

+ (NSString*)stringWithRepeatString:(char*)characters times:(unsigned int)repetitions;
{
    unsigned int stringLength = strlen(characters);
    unsigned int repeatStringLength = stringLength * repetitions + 1;

    char repeatString[repeatStringLength];

    for (unsigned int i = 0; i < repetitions; i++) {
        unsigned int pointerPosition = i * repetitions;
        memcpy(repeatString + pointerPosition, characters, stringLength);       
    }

    // Set terminating null
    repeatString[repeatStringLength - 1] = 0;

    return [NSString stringWithCString:repeatString];
}

если вы используете какао в Python, то вы можете просто сделать это, как PyObjC наполняет NSString со всем питоном класса.

в противном случае, есть два способа.

один из них-создать массив с той же строкой в нем n раз, и использовать componentsJoinedByString:. Что-то вроде этого:

NSMutableArray *repetitions = [NSMutableArray arrayWithCapacity:n];
for (NSUInteger i = 0UL; i < n; ++i)
    [repetitions addObject:inputString];
outputString = [repetitions componentsJoinedByString:@""];

другой способ-начать с пустого NSMutableString и добавьте к нему строку n раз, как это:

NSMutableString *temp = [NSMutableString stringWithCapacity:[inputString length] * n];
for (NSUInteger i = 0UL; i < n; ++i)
    [temp appendString:inputString];
outputString = [NSString stringWithString:temp];

вы может быть, удастся вырезать stringWithString: позвоните, если это нормально для вас, чтобы вернуть изменяемую строку здесь. В противном случае, вы, вероятно, должны вернуть неизменяемую строку, и stringWithString: сообщение здесь означает, что у вас есть две копии строки в памяти.

поэтому, я рекомендую componentsJoinedByString: решение.

[Edit: заимствованная идея для использования …WithCapacity: методы ответ Майка Макмастера.]