Pregunta

¿Hay algún atajo para (stringByAppendingString:) concatenación de cadenas en Objective-C, o atajos 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";
¿Fue útil?

Solución

Dos respuestas se me ocurre ... no es particularmente lo más agradable sólo tener un operador de concatenación.

En primer lugar, utilizar un NSMutableString, que tiene un método appendString, la eliminación de algunos de la necesidad de cadenas temporales adicionales.

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

Otros consejos

Una opción:

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

Otra opción:

supongo que no está satisfecho con múltiples APPENDs (a + b + c + d), en cuyo caso se podría hacer lo siguiente:

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

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

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

Eso también es útil para unir #defines:

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

Disfrute.

Sigo volviendo a este post y siempre terminan clasificación a través de 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];

Bueno, como cáncer de colon es una especie de símbolo especial, pero es de firma del método, es posible exted la NSString con categoría para añadir este no-idiomática estilo de la concatenación de cadenas:

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

Puede definir tantos argumentos separados por dos puntos que le resultan útiles ...; -)

Para obtener una buena medida, también he añadido concat: con argumentos variable que toma nil lista de cadenas terminado.

//  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);
}

Crear un método:

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

A continuación, en función de lo que se necesita en, pon tu campo de cadena o texto o lo que sea que el valor de retorno de esta función.

O, para crear un acceso directo, convertir el NSString en una cadena de C ++ y utilizar el signo '+' allí.

Utilice 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."];

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 alternativo: (si se quería hacer cumplir 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:@""];

Cuando la construcción de las solicitudes de servicios web, encuentro haciendo algo como lo siguiente es muy fácil y hace que la concatenación 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>"
};

Acceso directo mediante la creación de AppendString (AS) macro ...

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

Nota:

Si se utiliza una macro, por supuesto, sólo lo hace con argumentos variadic, véase la respuesta de 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];

Aquí está una manera simple, utilizando la nueva sintaxis literal de matriz:

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

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

Comience a ingresar "N" en su aplicación Xcode y se completará automáticamente en "NSString".Introduzca "str" ​​y se completará automáticamente en "stringByAppendingString".Entonces las pulsaciones de teclas son bastante limitadas.

Una vez que aprendas a presionar la tecla "@" y tabular, el proceso de escribir código legible ya no será un problema.Es sólo cuestión de adaptarse.

La única manera de hacer c = [a stringByAppendingString: b] más corto es el uso de autocompletar en torno al punto de st. El operador + es parte de C, que no sabe acerca de los objetos de Objective-C.

¿Qué tal acortar? stringByAppendingString y usar un #definir:

#define and stringByAppendingString

Por lo tanto usarías:

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

El problema es que solo funciona para dos cadenas, es necesario colocar corchetes adicionales para agregar más:

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

He intentado este código. que ha funcionado para mí.

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

intentaba lo siguiente en el panel lldb

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

que errores.

utilizar en su lugar alloc y initWithFormat método:

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

Esto es para un mejor registro, y el registro sólo - basado en dicius método excelente argumento múltiple. Defino una clase Logger, y lo llaman de esta manera:

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

Casi bueno, excepto tener que poner fin a los argumentos var con "nula", pero supongo que no hay forma de evitar eso 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://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 

Para única concat cuerdas, me gustaría definir una categoría de NSString y añadir un estático (+) Método de concatenación a lo que se ve exactamente igual que el método de registro anterior, excepto que devuelve la cadena. Está en NSString porque es un método de cadena, y es estática porque quiere crear una nueva cadena de las cadenas 1-N, no llamarlo en cualquiera de las cadenas que forman parte de la anexión.

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

Trate stringWithFormat:

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

Cuando se trata de cadenas menudo me resulta más fácil hacer que el archivo de origen ObjC ++, entonces puedo concatenar std :: cadenas utilizando 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()];

Mi método preferido es la siguiente:

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

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

Puede lograrlo mediante la adición del 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 para NSArray, creo que este es el método más rápido para concatenar cadenas.

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

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

Se puede utilizar como 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:@" "];

o

puede utilizar

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

Cualquiera de estas formas de trabajo, 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, sólo es necesario el carácter @ operador en la primera cuerda de la mezcla.

Sin embargo, no funciona con la inserción variable. Por eso, se puede utilizar esta solución extremadamente simple con la excepción de utilizar una macro en "gato" en lugar de "y" .

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

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

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, puede utilizar += operador para la misma de la siguiente manera ...

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

Imaginemos que u no saben cómo muchas cadenas allí.

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:@", "];
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top