web-dev-qa-db-ja.com

別の文字列を指定された回数繰り返すことによってNSStringを作成します

これは簡単なはずですが、最も簡単な解決策を見つけるのに苦労しています。

NSStringが必要です。これは、指定された回数だけ連結された別の文字列と同じです。

より良い説明のために、次のpythonの例を検討してください:

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

ヒントはありますか?


編集:

OmniFrameworksからのこの実装を見た後、 Mike McMasterの回答 によるソリューションに似たソリューションを投稿しました。

// 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

Omni Frameworks によるOpenExtensionsフレームワークについて The Omni Group による。

56
Sergio Acosta

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
159
tig
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
Mike McMaster

パフォーマンスについては、次のようなもので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クラスのカテゴリ拡張として書くことができます。おそらくそこに投入すべきチェックがいくつかありますが、これは簡単な要点です。

4
Lee Calloway

上記の最初の方法は、単一の文字用です。これは文字列用です。単一の文字にも使用できますが、オーバーヘッドが大きくなります。

+ (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
user144851

PythonでCocoaを使用している場合は、PyObjCがNSStringにPython unicodeクラスの機能をすべて組み込んでいるため、そうすることができます。

それ以外の場合、2つの方法があります。

1つは、同じ文字列を含む配列をn回作成し、componentsJoinedByString:を使用することです。このようなもの:

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

もう1つの方法は、空の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:メッセージは、メモリに文字列の2つのコピーがあることを意味します。

したがって、componentsJoinedByString:ソリューションをお勧めします。

[編集: Mike McMasterの回答…WithCapacity:メソッドを使用するための借用アイデア]

1
Peter Hosey