2008-11-04 23 views
51

Điều này sẽ dễ dàng, nhưng tôi đang gặp khó khăn trong việc tìm ra giải pháp đơn giản nhất.Tạo NSString bằng cách lặp lại một chuỗi khác với số lần nhất định

Tôi cần số NSString bằng một chuỗi khác được nối với chính nó một số lần nhất định.

Đối với một lời giải thích tốt hơn, xem xét ví dụ python sau:

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

Bất kỳ gợi ý?


EDIT:

tôi sẽ gửi một giải pháp tương tự cho từng người Mike McMaster's answer, sau khi xem xét thực hiện điều này từ 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]; 
} 

Mã sao chép từ file:

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

trên khung OpenExtensions từ Omni Frameworks bởi The Omni Group.

Trả lời

145

Có một phương pháp gọi là stringByPaddingToLength:withString:startingAtIndex::

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

Lưu ý rằng nếu bạn muốn 3 abc của, vì sử dụng 9 (3 * [@"abc" length]) hoặc tạo loại như thế này:

@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 
+3

+1 để thực hiện tất cả trong một cuộc gọi duy nhất tới thư viện chuẩn. Và đây là cách tôi sử dụng nó để tạo danh sách các dấu chấm hỏi được phân tách bằng dấu phẩy (cho ăn cho SQLite) - '[@" "stringByPaddingToLength: [số trường] * withString: 2-1" @? ", Bắt đầuAtIndex: 0] '. – noamtm

7
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" 
+0

Tôi đã cố gắng để tìm ra cái gì đó đơn giản hơn, nhưng tôi nghĩ đây là cách ngắn nhất. –

+0

Tôi đã làm cho nó hiệu quả hơn một chút kể từ khi chấp nhận trước thời gian xác định trước và có dung lượng = [độ dài ban đầu] * lần –

+1

Chỉ để hoàn thành, nếu vì lý do nào đó bạn muốn sử dụng số lớn, bạn có thể cải thiện điều này bằng cách tái sử dụng năng lượng- của hai nối (ví dụ: foo * 10 = foo * 2 + foo * 8; foo * 8 = foo * 4 + foo * 4; foo * 4 = foo * 2 + foo * 2 -> 3 thao tác concat thay vì 9) . –

1

Nếu bạn đang sử dụng Cocoa bằng Python, sau đó bạn chỉ có thể làm điều đó, như PyObjC thấm đẫm NSString với tất cả khả năng của Python unicode lớp của.

Nếu không, có hai cách.

Một là tạo một mảng có cùng một chuỗi trong đó n lần và sử dụng componentsJoinedByString:. Một cái gì đó như thế này:

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

Một cách khác sẽ được bắt đầu với một sản phẩm nào NSMutableString và thêm chuỗi để nó n lần, như thế này:

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

Bạn có thể cắt ra stringWithString: gọi nếu OK để bạn trả lại chuỗi có thể thay đổi tại đây. Nếu không, bạn có thể phải trả về một chuỗi không thay đổi được và thông báo stringWithString: ở đây có nghĩa là bạn có hai bản sao của chuỗi trong bộ nhớ.

Vì vậy, tôi đề xuất giải pháp componentsJoinedByString:.

[Edit: Mượn ý tưởng để sử dụng …WithCapacity: phương pháp từ Mike McMaster's answer.]

+0

Cảm ơn bạn đã thay thế bằng cách sử dụng componentsJoinedByString. –

+0

Vâng, gợi ý tốt. Có lẽ một chút teeny hiệu quả hơn là giải pháp của tôi (được thừa nhận là chung chung). –

4

Đối với hiệu suất, bạn có thể thả vào C với một cái gì đó như thế này:

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

Điều này có thể được viết như một phần mở rộng chủng loại trên lớp NSString. Có lẽ một số kiểm tra nên được ném vào đó, nhưng đây là ý chính của nó.

+0

Ý tưởng tuyệt vời, đặc biệt cho các tình huống đói kém hiệu suất. Cảm ơn! –

+0

kiểm tra xem có lặp lại> 0 không? –

+0

David, lặp lại là một int unsigned – jessecurry

2

Phương pháp đầu tiên ở trên là dành cho một ký tự đơn. Điều này là dành cho một chuỗi ký tự. Nó có thể được sử dụng cho một nhân vật duy nhất quá nhưng có nhiều chi phí hơn.

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

Có một lỗi, tôi nghĩ rằng, bên trong cho chu kỳ: 'unsigned int pointerPosition = i * lặp lại; ' nên ' unsigned int pointerPosition = i * StringLength;' nơi ** i * lặp lại ** trở thành ** i * stringLength **. – mginius

Các vấn đề liên quan