Ярлыки в Objective-C для объединения строк NSS - PullRequest
1090 голосов
/ 04 февраля 2009

Есть ли какие-либо ярлыки для (stringByAppendingString:) конкатенации строк в Objective-C или ярлыки для работы с NSString в целом?

Например, я хотел бы сделать:

NSString *myString = @"This";
NSString *test = [myString stringByAppendingString:@" is just a test"];

что-то вроде:

string myString = "This";
string test = myString + " is just a test";

Ответы [ 30 ]

1097 голосов
/ 04 февраля 2009

Опция:

[NSString stringWithFormat:@"%@/%@/%@", one, two, three];

Другой вариант:

Полагаю, вам не нравятся множественные добавления (a + b + c + d), в этом случае вы можете сделать:

NSLog(@"%@", [Util append:one, @" ", two, nil]); // "one two"
NSLog(@"%@", [Util append:three, @"/", two, @"/", one, nil]); // three/two/one

используя что-то вроде

+ (NSString *) append:(id) first, ...
{
    NSString * result = @"";
    id eachArg;
    va_list alist;
    if(first)
    {
        result = [result stringByAppendingString:first];
        va_start(alist, first);
        while (eachArg = va_arg(alist, id)) 
        result = [result stringByAppendingString:eachArg];
        va_end(alist);
    }
    return result;
}
601 голосов
/ 04 февраля 2009

Я могу придумать два ответа ... ни один из них не так приятен, как просто иметь оператор конкатенации.

Во-первых, используйте NSMutableString, который имеет метод appendString, избавляя от необходимости дополнительных временных строк.

Во-вторых, используйте NSArray для объединения с помощью метода componentsJoinedByString.

147 голосов
/ 17 марта 2011

Если у вас есть 2 NSString литерал , вы также можете просто сделать это:

NSString *joinedFromLiterals = @"ONE " @"MILLION " @"YEARS " @"DUNGEON!!!";

Это также полезно для присоединения к #defines:

#define STRINGA @"Also, I don't know "
#define STRINGB @"where food comes from."
#define JOINED STRINGA STRINGB

Наслаждайтесь.

69 голосов
/ 11 августа 2012

Я продолжаю возвращаться к этому посту и всегда заканчиваю сортировкой ответов, чтобы найти это простое решение, которое работает с таким количеством переменных, сколько необходимо:

[NSString stringWithFormat:@"%@/%@/%@", three, two, one];

Например:

NSString *urlForHttpGet = [NSString stringWithFormat:@"http://example.com/login/username/%@/userid/%i", userName, userId];
43 голосов
/ 16 марта 2012

Ну, так как двоеточие является своего рода специальным символом, но является частью сигнатуры метода, можно добавить NSString с категорией, чтобы добавить этот неидиоматический стиль конкатенации строк:

[@"This " : @"feels " : @"almost like " : @"concatenation with operators"];

Вы можете определить столько аргументов, разделенных двоеточиями, сколько считаете полезным ...; -)

Для удобства я также добавил concat: с переменными аргументами, которые принимают nil завершенный список строк.

//  NSString+Concatenation.h

#import <Foundation/Foundation.h>

@interface NSString (Concatenation)

- (NSString *):(NSString *)a;
- (NSString *):(NSString *)a :(NSString *)b;
- (NSString *):(NSString *)a :(NSString *)b :(NSString *)c;
- (NSString *):(NSString *)a :(NSString *)b :(NSString *)c :(NSString *)d;

- (NSString *)concat:(NSString *)strings, ...;

@end

//  NSString+Concatenation.m

#import "NSString+Concatenation.h"

@implementation NSString (Concatenation)

- (NSString *):(NSString *)a { return [self stringByAppendingString:a];}
- (NSString *):(NSString *)a :(NSString *)b { return [[self:a]:b];}
- (NSString *):(NSString *)a :(NSString *)b :(NSString *)c
    { return [[[self:a]:b]:c]; }
- (NSString *):(NSString *)a :(NSString *)b :(NSString *)c :(NSString *)d
    { return [[[[self:a]:b]:c]:d];}

- (NSString *)concat:(NSString *)strings, ...
{
    va_list args;
    va_start(args, strings);

    NSString *s;    
    NSString *con = [self stringByAppendingString:strings];

    while((s = va_arg(args, NSString *))) 
        con = [con stringByAppendingString:s];

    va_end(args);
    return con;
}
@end

//  NSString+ConcatenationTest.h

#import <SenTestingKit/SenTestingKit.h>
#import "NSString+Concatenation.h"

@interface NSString_ConcatenationTest : SenTestCase

@end

//  NSString+ConcatenationTest.m

#import "NSString+ConcatenationTest.h"

@implementation NSString_ConcatenationTest

- (void)testSimpleConcatenation 
{
    STAssertEqualObjects([@"a":@"b"], @"ab", nil);
    STAssertEqualObjects([@"a":@"b":@"c"], @"abc", nil);
    STAssertEqualObjects([@"a":@"b":@"c":@"d"], @"abcd", nil);
    STAssertEqualObjects([@"a":@"b":@"c":@"d":@"e"], @"abcde", nil);
    STAssertEqualObjects([@"this " : @"is " : @"string " : @"concatenation"],
     @"this is string concatenation", nil);
}

- (void)testVarArgConcatenation 
{
    NSString *concatenation = [@"a" concat:@"b", nil];
    STAssertEqualObjects(concatenation, @"ab", nil);

    concatenation = [concatenation concat:@"c", @"d", concatenation, nil];
    STAssertEqualObjects(concatenation, @"abcdab", nil);
}
36 голосов
/ 04 октября 2011

Создать метод:

- (NSString *)strCat: (NSString *)one: (NSString *)two
{
    NSString *myString;
    myString = [NSString stringWithFormat:@"%@%@", one , two];
    return myString;
}

Затем в любой функции, в которой вы нуждаетесь, установите строку или текстовое поле или что-либо еще в качестве возвращаемого значения этой функции.

Или, чтобы сделать ярлык, преобразовать строку NSString в строку C ++ и использовать там «+».

32 голосов
/ 26 июля 2010

Используйте этот способ:

NSString *string1, *string2, *result;

string1 = @"This is ";
string2 = @"my string.";

result = [result stringByAppendingString:string1];
result = [result stringByAppendingString:string2];

OR

result = [result stringByAppendingString:@"This is "];
result = [result stringByAppendingString:@"my string."];
29 голосов
/ 31 мая 2013

Macro:

// stringConcat(...)
//     A shortcut for concatenating strings (or objects' string representations).
//     Input: Any number of non-nil NSObjects.
//     Output: All arguments concatenated together into a single NSString.

#define stringConcat(...) \
    [@[__VA_ARGS__] componentsJoinedByString:@""]

Контрольные примеры:

- (void)testStringConcat {
    NSString *actual;

    actual = stringConcat(); //might not make sense, but it's still a valid expression.
    STAssertEqualObjects(@"", actual, @"stringConcat");

    actual = stringConcat(@"A");
    STAssertEqualObjects(@"A", actual, @"stringConcat");

    actual = stringConcat(@"A", @"B");
    STAssertEqualObjects(@"AB", actual, @"stringConcat");

    actual = stringConcat(@"A", @"B", @"C");
    STAssertEqualObjects(@"ABC", actual, @"stringConcat");

    // works on all NSObjects (not just strings):
    actual = stringConcat(@1, @" ", @2, @" ", @3);
    STAssertEqualObjects(@"1 2 3", actual, @"stringConcat");
}

Альтернативный макрос: (если вы хотите ввести минимальное количество аргументов)

// stringConcat(...)
//     A shortcut for concatenating strings (or objects' string representations).
//     Input: Two or more non-nil NSObjects.
//     Output: All arguments concatenated together into a single NSString.

#define stringConcat(str1, str2, ...) \
    [@[ str1, str2, ##__VA_ARGS__] componentsJoinedByString:@""];
27 голосов
/ 16 марта 2012

При создании запросов для веб-сервисов, я считаю, что сделать что-то вроде следующего очень легко и делает сцепление читаемым в Xcode:

NSString* postBody = {
    @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
    @"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
    @" <soap:Body>"
    @"  <WebServiceMethod xmlns=\"\">"
    @"   <parameter>test</parameter>"
    @"  </WebServiceMethod>"
    @" </soap:Body>"
    @"</soap:Envelope>"
};
24 голосов
/ 18 июля 2009

Ярлык путем создания макроса AppendString (AS) ...

#define AS(A,B)    [(A) stringByAppendingString:(B)]<br>
NSString *myString = @"This";

NSString *test = AS(myString,@" is just a test");

Примечание:

Если вы используете макрос, конечно, просто делайте это с переменными аргументами, смотрите ответ EthanB.

...