objective-c nsstring string-concatenation

objective c - Atajos en Objective-C para concatenar NSStrings



string-concatenation (30)

¿Hay algún acceso directo a ( stringByAppendingString: concatenación de cadenas en Objective-C, o accesos directos para trabajar con NSString en general?

Por ejemplo, me gustaría hacer:

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

algo más como

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


Una opción:

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

Otra opción:

Supongo que no estás contento con varios apéndices (a + b + c + d), en cuyo caso podrías hacer:

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

usando algo como

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


¿Qué hay de acortar stringByAppendingString y usar un #define :

#define and stringByAppendingString

Así usarías:

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

El problema es que solo funciona para dos cadenas, se requiere que envuelvas corchetes adicionales para más apéndices:

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


Al crear solicitudes para servicios web, me parece que hacer algo como lo siguiente es muy fácil y hace que la concatenación sea legible en 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>" };


Aquí hay una forma simple, usando la nueva sintaxis literal de matriz:

NSString * s = [@[@"one ", @"two ", @"three"] componentsJoinedByString:@""]; ^^^^^^^ create array ^^^^^ ^^^^^^^ concatenate ^^^^^


Atajo al crear la macro AppendString (AS) ...

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

Nota:

Si usa una macro, por supuesto, hágalo solo con argumentos variados, vea la respuesta de EthanB.


Bueno, como los dos puntos son una especie de símbolo especial, pero forman parte de la firma del método, es posible enviar la NSString con la categoría para agregar este estilo no idiomático de concatenación de cadenas:

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

Puedes definir tantos argumentos separados por dos puntos como encuentres útil ... ;-)

Para una buena medida, también he agregado concat: con argumentos variables que toman una lista de cadenas terminada en 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); }


Cualquiera de estos formatos funciona en XCode7 cuando probé:

NSString *sTest1 = {@"This" " and that" " and one more"}; NSString *sTest2 = { @"This" " and that" " and one more" }; NSLog(@"/n%@/n/n%@",sTest1,sTest2);

Por alguna razón, solo necesitas el carácter de operador @ en la primera cadena de la mezcla.

Sin embargo, no funciona con la inserción de variables. Para eso, puede usar esta solución extremadamente simple con la excepción de usar una macro en "cat" en lugar de "y".


Cuando trato con cadenas a menudo, me resulta más fácil crear el archivo fuente ObjC ++, luego puedo concatenar cadenas std :: usando el segundo método que se muestra en la pregunta.

std::string stdstr = [nsstr UTF8String]; //easier to read and more portable string manipulation goes here... NSString* nsstr = [NSString stringWithUTF8String:stdstr.c_str()];


En Swift

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"

Además, puedes usar el operador += para lo mismo que a continuación ...

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


Estaba intentando lo siguiente en el panel lldb

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

qué errores.

En su lugar, utilice el método alloc y initWithFormat :

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


Esto es para un mejor registro y solo para el registro, basado en el excelente método de múltiples argumentos de dicius. Defino una clase de registrador, y la llamo así:

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

Casi bien, excepto que tengo que terminar las variables con "nil", pero supongo que no hay forma de evitarlo en 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://.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

Para concatenar solo cadenas, definiría una Categoría en NSString y le agregaría un método estático (+) de concatenación que se parece exactamente al método de registro anterior, excepto que devuelve la cadena. Está en NSString porque es un método de cadena y es estático porque desea crear una cadena nueva a partir de cadenas 1-N, no llamarla en ninguna de las cadenas que forman parte del anexo.


Imaginemos que no sabes cuántas cuerdas hay.

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


Intente stringWithFormat:

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


La única forma de c = [a stringByAppendingString: b] es usar autocompletar alrededor del punto st . El operador + es parte de C, que no conoce los objetos de Objective-C.


Mi método preferido es este:

NSString *firstString = @"foo"; NSString *secondString = @"bar"; NSString *thirdString = @"baz"; NSString *joinedString = [@[firstString, secondString, thirdString] join];

Puede lograrlo agregando el método de unión a NSArray con una categoría:

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

@[] es la definición corta de NSArray , creo que este es el método más rápido para concatenar cadenas.

Si no desea utilizar la categoría, use directamente el método componentsJoinedByString: :

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


Para todos los amantes de Objective C que necesitan esto en una prueba de interfaz de usuario:

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


Probé este código. ha funcionado para mi

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


Puedes usar NSArray como

NSString *string1=@"This" NSString *string2=@"is just" NSString *string3=@"a test" NSArray *myStrings = [[NSArray alloc] initWithObjects:string1, string2, string3,nil]; NSString *fullLengthString = [myStrings componentsJoinedByString:@" "];

o

puedes usar

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


Puedo pensar en dos respuestas ... ninguna de las dos es tan agradable como tener un operador de concatenación.

Primero, use un NSMutableString , que tiene un método appendString , eliminando parte de la necesidad de cadenas temporales adicionales.

En segundo lugar, use un NSArray para concatenar a través del método componentsJoinedByString .


Si tiene 2 literales NSString, también puede hacer esto:

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

Eso también es útil para unirte a #defines:

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

Disfrutar.


Sigo volviendo a esta publicación y siempre termino ordenando las respuestas para encontrar esta solución simple que funciona con tantas variables como sea necesario:

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

Por ejemplo:

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


Use de esta manera:

NSString *string1, *string2, *result; string1 = @"This is "; string2 = @"my string."; result = [result stringByAppendingString:string1]; result = [result stringByAppendingString:string2];

O

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


crear un método ......

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

Luego, en cualquier función en la que lo necesite, configure su cadena o campo de textfield o lo que sea al valor de retorno de esta función.

O lo que puede hacer para hacer un acceso directo es convertir el NSString en una cadena c ++ y usar el ''+'' allí.

¡¡¡¡¡Espero que esto ayude!!!!!


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

Casos de prueba:

- (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"); }

Macro alternativa: (si desea imponer un número mínimo de argumentos)

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


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


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 *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 *myString = @"This"; NSString *test = [myString stringByAppendingString:@" is just a test"];

Después de un par de años con Objective CI, creo que esta es la mejor manera de trabajar con Objective C para lograr lo que está tratando de lograr.

Comience a teclear "N" en su aplicación Xcode y se autocompleta a "NSString". teclee "str" ​​y se autocompleta a "stringByAppendingString". Así que las pulsaciones son bastante limitadas.

Una vez que aprendes a golpear la tecla "@" y el proceso de escritura de código legible ya no es un problema. Es sólo una cuestión de adaptación.


NSString *result=[NSString stringWithFormat:@"%@ %@", @"Hello", @"World"];


listOfCatalogIDs =[@[@"id[]=",listOfCatalogIDs] componentsJoinedByString:@""];