Crear NSString repitiendo otra cadena un número determinado de veces


Esto debería ser fácil, pero estoy teniendo dificultades para encontrar la solución más fácil.

Necesito un NSString que sea igual a otra cadena concatenada consigo misma un número dado de veces.

Para una mejor explicación, considere el siguiente ejemplo de python:

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

Alguna pista?


EDITAR:

Iba a publicar una solución similar a la de La respuesta de Mike McMaster , después de mirar esta implementación desde el 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];
}

Código reproducido del archivo:

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

En el framework OpenExtensions de Omni Frameworks por El Grupo Omni.

Author: Community, 2008-11-04

5 answers

Hay un método llamado stringByPaddingToLength:withString:startingAtIndex::

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

Ten en cuenta que si quieres 3 abc, entonces usa 9 (3 * [@"abc" length]) o crea una categoría como esta:

@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
 154
Author: tig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-06 22:40:43
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"
 7
Author: Mike McMaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-04 05:19:11

Para el rendimiento, podría caer en C con algo como esto:

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

Esto podría escribirse como una extensión de categoría en la clase NSString. Probablemente hay algunos cheques que deberían ser lanzados allí, pero esta es la esencia directa de la misma.

 4
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-25 03:13:25

El primer método anterior es para un solo carácter. Este es para una cadena de caracteres. También podría usarse para un solo carácter, pero tiene más sobrecarga.

+ (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];
}
 2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-25 04:05:32

Si estás usando Cocoa en Python, entonces puedes hacer eso, ya que PyObjC impregna NSString con todas las habilidades de la clase Python unicode.

De lo contrario, hay dos maneras.

Uno es crear una matriz con la misma cadena n veces, y usar componentsJoinedByString:. Algo como esto:

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

La otra forma sería comenzar con un NSMutableString vacío y agregarle la cadena n veces, así:

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

Es posible que pueda cortar la llamada stringWithString: si está bien para usted para devolver una cadena mutable aquí. De lo contrario, probablemente debería devolver una cadena inmutable, y el mensaje stringWithString: aquí significa que tiene dos copias de la cadena en memoria.

Por lo tanto, recomiendo la solución componentsJoinedByString:.

[Editar: Idea prestada para usar …WithCapacity:métodos de Respuesta de Mike McMaster .]

 1
Author: Peter Hosey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:31