Создать NSString, повторяя другую строку заданное количество раз - PullRequest
55 голосов
/ 04 ноября 2008

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

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

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

>> 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 Frameworks от The Omni Group .

Ответы [ 5 ]

157 голосов
/ 05 января 2011

Существует метод с именем stringByPaddingToLength:withString:startingAtIndex::

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

Обратите внимание, что если вы хотите 3 азбуки, используйте 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
7 голосов
/ 04 ноября 2008
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"
4 голосов
/ 25 июля 2009

Для производительности вы можете заскочить в 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. Вероятно, есть несколько проверок, которые следует добавить туда, но в этом суть.

2 голосов
/ 25 июля 2009

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

+ (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];
}
1 голос
/ 04 ноября 2008

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

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

Один - создать массив с одной и той же строкой 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:.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...