it-swarm.com.ru

Ярлыки в Objective-C для объединения строк NSS

Существуют ли какие-либо сочетания клавиш (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";
1090
typeoneerror

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

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

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

601
Chris Blackwell

Опция:

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

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

Наслаждаться.

147
Johannes Fahrenkrug

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

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

Например:

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

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

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

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

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

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

36
Sidd Menon

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

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."];
32
Taimur Ajmal

Макро:

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

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

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

 # определить AS (A, B) [(A) stringByAppendingString: (B)]
NSString * myString = @ "This"; NSString * test = AS (myString, @ "это просто тест");

Примечание:

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

24
Jim Logan
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];
13
coder284

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

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

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

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

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

9
Ian Clay
NSString *result=[NSString stringWithFormat:@"%@ %@", @"Hello", @"World"];
8
Gobi M

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

#define and stringByAppendingString

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

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

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

NSString* myString = [[@"Hello" and: @" world"] and: @" again"];
8
Sunday Ironfoot

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

8
user23743

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

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

Попытка следующего в панели lldb

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

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

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

[[NSString alloc] initWithFormat:@"%@/%@/%@", @"three", @"two", @"one"];
6
Anthony De Souza

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

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

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

Logger.h

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

Logger.m

@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 

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

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

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

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

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

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

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

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

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

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

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

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

При работе со строками часто мне проще создать исходный файл 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()];
3
iforce2d

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

NSString *[email protected]"This"

NSString *[email protected]"is just"

NSString *[email protected]"a test"  

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

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

или же

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

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

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

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

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

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

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

1
Volomike

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

-(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];
}
1
netshark1000
listOfCatalogIDs =[@[@"id[]=",listOfCatalogIDs] componentsJoinedByString:@""];
0
user4951

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

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:@", "];
0
Resty

В Свифт

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"
0
Suryakant Sharma