Вопрос

Есть ли какие-нибудь короткие пути к (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";
Это было полезно?

Решение

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

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

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

Другие советы

Вариант:

[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;
}

Если у вас есть 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

Наслаждайся.

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

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

Например:

NSString *urlForHttpGet = [NSString stringWithFormat:@"http://example.com/login/username/%@/userid/%i", userName, userId];

Ну, поскольку двоеточие - это своего рода специальный символ, но является часть сигнатуры метода, можно извлечь 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);
}

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

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

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

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

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

NSString *string1, *string2, *result;

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

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

или

result = [result stringByAppendingString:@"This is "];
result = [result stringByAppendingString:@"my string."];

Макрос:

// 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:@""];

При создании запросов для веб-служб я нахожу, что делать что-то вроде следующего очень просто и делает конкатенацию читаемой в 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>"
};

Сократите путь, создав макрос AppendString (AS) ...

#define AS(A,B)    [(A) stringByAppendingString:(B)]
NSString *myString = @"This"; NSString *test = AS(myString,@" is just a test");

Примечание:

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

NSString *label1 = @"Process Name: ";
NSString *label2 = @"Process Id: ";
NSString *processName = [[NSProcessInfo processInfo] processName];
NSString *processID = [NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]];
NSString *testConcat = [NSString stringWithFormat:@"%@ %@ %@ %@", label1, processName, label2, processID];

Вот простой способ, использующий новый синтаксис литерала массива:

NSString * s = [@[@"one ", @"two ", @"three"] componentsJoinedByString:@""];
                  ^^^^^^^ create array ^^^^^
                                               ^^^^^^^ concatenate ^^^^^
NSString *myString = @"This";
NSString *test = [myString stringByAppendingString:@" is just a test"];

После нескольких лет работы с Objective C я думаю, что это лучший способ работать с Objective C для достижения того, чего вы пытаетесь достичь.

Начните вводить "N" в вашем приложении Xcode, и оно автоматически завершится до "NSString".введите "str", и он автоматически завершится до "stringByAppendingString".Таким образом, количество нажатий клавиш весьма ограничено.

Как только вы научитесь нажимать клавишу "@" и делать табуляцию, процесс написания читаемого кода больше не станет проблемой.Это всего лишь вопрос адаптации.

Единственный способ сделать c = [a stringByAppendingString: b] еще короче - использовать автозаполнение примерно в st точка.Тот Самый + operator является частью C, который не знает об объектах Objective-C.

Как насчет сокращения stringByAppendingString и использовать #определить:

#define and stringByAppendingString

Таким образом, вы бы использовали:

NSString* myString = [@"Hello " and @"world"];

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

NSString* myString = [[@"Hello" and: @" world"] and: @" again"];
NSString *result=[NSString stringWithFormat:@"%@ %@", @"Hello", @"World"];
NSString *label1 = @"Process Name: ";
NSString *label2 = @"Process Id: ";
NSString *processName = [[NSProcessInfo processInfo] processName];
NSString *processID = [NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]];
NSString *testConcat = [NSString stringWithFormat:@"%@ %@ %@ %@", label1, processName, label2, processID];

Я попробовал этот код.у меня это сработало.

NSMutableString * myString=[[NSMutableString alloc]init];
myString=[myString stringByAppendingString:@"first value"];
myString=[myString stringByAppendingString:@"second string"];

Пробовал следующее в lldb панель

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

какие ошибки.

вместо этого используйте alloc и initWithFormat способ:

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

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

[Logger log: @"foobar ", @" asdads ", theString, nil];

Почти хорошо, за исключением необходимости заканчивать аргументы var "nil", но я полагаю, что в Objective-C.

Регистратор.h

@interface Logger : NSObject {
}
+ (void) log: (id) first, ...;
@end

Регистратор.м

@implementation Logger

+ (void) log: (id) first, ...
{
    // TODO: make efficient; handle arguments other than strings
    // thanks to @diciu http://stackoverflow.com/questions/510269/how-do-i-concatenate-strings-in-objective-c
    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);
    }
    NSLog(@"%@", result);
}

@end 

Для того, чтобы только конкат strings, я бы определил категорию в NSString и добавил к ней статический (+) метод конкатенации, который выглядит точно так же, как метод log выше, за исключением того, что он возвращает строку.Он находится в NSString, потому что это строковый метод, и он статичен, потому что вы хотите создать новую строку из 1-N строк, а не вызывать ее ни для одной из строк, которые являются частью добавления.

NSNumber *lat = [NSNumber numberWithDouble:destinationMapView.camera.target.latitude];
NSNumber *lon = [NSNumber numberWithDouble:destinationMapView.camera.target.longitude];
NSString *DesconCatenated = [NSString stringWithFormat:@"%@|%@",lat,lon];

Попробуйте stringWithFormat:

NSString *myString = [NSString stringWithFormat:@"%@ %@ %@ %d", "The", "Answer", "Is", 42];

Когда я часто имею дело со строками, мне проще создать исходный файл ObjC ++, тогда я могу объединить std::strings, используя второй метод, показанный в вопросе.

std::string stdstr = [nsstr UTF8String];

//easier to read and more portable string manipulation goes here...

NSString* nsstr = [NSString stringWithUTF8String:stdstr.c_str()];

Мой предпочтительный метод заключается в следующем:

NSString *firstString = @"foo";
NSString *secondString = @"bar";
NSString *thirdString = @"baz";

NSString *joinedString = [@[firstString, secondString, thirdString] join];

Вы можете достичь этого, добавив метод join в NSArray с категорией:

#import "NSArray+Join.h"
@implementation NSArray (Join)
-(NSString *)join
{
    return [self componentsJoinedByString:@""];
}
@end

@[] это краткое определение для NSArray, Я думаю, что это самый быстрый метод объединения строк.

Если вы не хотите использовать эту категорию, используйте непосредственно componentsJoinedByString: способ:

NSString *joinedString = [@[firstString, secondString, thirdString] componentsJoinedByString:@""];

Вы можете использовать NSArray как

NSString *string1=@"This"

NSString *string2=@"is just"

NSString *string3=@"a test"  

NSArray *myStrings = [[NSArray alloc] initWithObjects:string1, string2, string3,nil];

NSString *fullLengthString = [myStrings componentsJoinedByString:@" "];

или

вы можете использовать

NSString *imageFullName=[NSString stringWithFormat:@"%@ %@ %@.", string1,string2,string3];

Любой из этих форматов работал в XCode7, когда я тестировал:

NSString *sTest1 = {@"This" " and that" " and one more"};
NSString *sTest2 = {
  @"This"
  " and that"
  " and one more"
};

NSLog(@"\n%@\n\n%@",sTest1,sTest2);

По какой-то причине вам нужен только символ @ operator в первой строке микса.

Однако это не работает при вставке переменной.Для этого вы можете использовать это чрезвычайно простое решение за исключением использования макроса для "cat" вместо "и".

Для всех любителей Objective C, которым это нужно в UI-тестировании:

-(void) clearTextField:(XCUIElement*) textField{

    NSString* currentInput = (NSString*) textField.value;
    NSMutableString* deleteString = [NSMutableString new];

    for(int i = 0; i < currentInput.length; ++i) {
        [deleteString appendString: [NSString stringWithFormat:@"%c", 8]];
    }
    [textField typeText:deleteString];
}
listOfCatalogIDs =[@[@"id[]=",listOfCatalogIDs] componentsJoinedByString:@""];

В Быстрый

let str1 = "This"
let str2 = "is just a test"

var appendStr1 = "\(str1) \(str2)" // appendStr1 would be "This is just a test"
var appendStr2 = str1 + str2 // // appendStr2 would be "This is just a test"

Кроме того, вы можете использовать += оператор для того же, что и ниже...

var str3 = "Some String" 
str3 += str2            // str3 would be "Some String is just a test"

Давайте представим, что вы не знаете, сколько там строк.

NSMutableArray *arrForStrings = [[NSMutableArray alloc] init];
for (int i=0; i<[allMyStrings count]; i++) {
    NSString *str = [allMyStrings objectAtIndex:i];
    [arrForStrings addObject:str];
}
NSString *readyString = [[arrForStrings mutableCopy] componentsJoinedByString:@", "];
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top