web-dev-qa-db-fra.com

Raccourcis dans Objective-C pour concaténer NSStrings

Existe-t-il des raccourcis vers la concaténation de chaînes (stringByAppendingString:) dans Objective-C ou des raccourcis pour utiliser NSString en général?

Par exemple, j'aimerais faire:

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

quelque chose de plus comme:

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

Deux réponses auxquelles je peux penser… ni l’une ni l’autre n’est aussi agréable à faire qu’un simple opérateur de concaténation.

Commencez par utiliser une méthode NSMutableString, qui utilise une méthode appendString, éliminant ainsi le besoin de chaînes temporaires supplémentaires.

Deuxièmement, utilisez un NSArray pour concaténer via la méthode componentsJoinedByString.

605
Chris Blackwell

Une option:

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

Une autre option:

Je suppose que vous n'êtes pas satisfait de plusieurs ajouts (a + b + c + d), auquel cas vous pouvez faire:

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

en utilisant quelque chose comme

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

Si vous avez 2 NSString littéraux, vous pouvez simplement faire ceci:

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

C'est également utile pour rejoindre #defines:

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

Prendre plaisir.

148

Je reviens sans cesse sur ce post et je finis toujours par trier les réponses pour trouver cette solution simple qui fonctionne avec autant de variables que nécessaire:

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

Par exemple:

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

Eh bien, comme les deux points sont une sorte de symbole spécial, mais fait partie de la signature de la méthode, il est possible d'extinguer le NSString avec la catégorie à ajouter. ce non-idiomatique style de concaténation de chaînes:

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

Vous pouvez définir autant d'arguments séparés par des deux-points que vous trouvez utiles ... ;-)

Pour une bonne mesure, j'ai également ajouté concat: avec des arguments variables qui prennent la liste de chaînes terminée par 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);
}
44
Palimondo

Créer une méthode:

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

Puis, quelle que soit la fonction dans laquelle vous en avez besoin, définissez votre chaîne, votre champ de texte ou autre sur la valeur de retour de cette fonction.

Ou, pour créer un raccourci, convertissez NSString en chaîne C++ et utilisez le '+' ici.

42
Sidd Menon

Utilisez cette manière:

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

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

Cas de test:

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

Autre macro: (si vous voulez appliquer un nombre minimum d'arguments)

// 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

Lors de la création de demandes de services Web, je trouve très simple de faire quelque chose comme ceci et de rendre la concaténation lisible dans 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

Raccourci en créant une macro AppendString (AS) ...

 # définir AS (A, B) [(A) stringByAppendingString: (B)]
NSString * myString = @ "This"; NSString * test = AS (myString, @ "n'est qu'un test");

Note:

Si vous utilisez une macro, bien sûr, faites-le simplement avec des arguments variadiques, voir la réponse d'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

Voici un moyen simple, en utilisant la nouvelle syntaxe littérale de tableau:

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

Après quelques années maintenant avec Objective C, je pense que c’est la meilleure façon de travailler avec Objective C pour atteindre ce que vous essayez d’atteindre.

Commencez à saisir "N" dans votre application Xcode et la complétion automatique en "NSString". saisissez "str" ​​et il complète automatiquement "stringByAppendingString". Donc, les frappes sont assez limitées.

Une fois que vous avez le coup de frapper la touche "@" et que la tabulation du processus d'écriture de code lisible ne devient plus un problème. C'est juste une question d'adaptation.

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

Pourquoi ne pas raccourcir stringByAppendingString et utiliser un # define:

#define and stringByAppendingString

Ainsi, vous utiliseriez:

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

Le problème est que cela ne fonctionne que pour deux chaînes, vous devez envelopper des crochets supplémentaires pour plusieurs ajouts:

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

La seule façon de raccourcir c = [a stringByAppendingString: b] consiste à utiliser la fonction de saisie semi-automatique autour du point st. L'opérateur + fait partie de C, qui ne connaît pas les objets Objective-C.

8
user23743

J'ai essayé ce code. ça a fonctionné pour moi.

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

J'essayais ce qui suit dans le volet lldb

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

quelles erreurs.

utilisez plutôt alloc et la méthode initWithFormat:

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

C’est pour une meilleure journalisation, et uniquement pour la journalisation - basée sur la excellente méthode à plusieurs arguments de dicius. Je définis une classe Logger et l’appelle comme suit:

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

Presque bon, sauf qu'il faut mettre fin aux arguments avec "nil", mais je suppose qu'il n'y a aucune solution de ce genre dans Objective-C.

Logger.h

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

Enregistreur.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 

Afin de ne faire que concat chaînes, je définirais une catégorie sur NSString et y ajouterais une méthode de concaténation statique (+) qui ressemble exactement à la méthode de journalisation ci-dessus, sauf qu'elle renvoie la chaîne. C'est sur NSString parce que c'est une méthode de chaîne, et statique car vous voulez créer une nouvelle chaîne à partir de chaînes 1-N, et non l'appeler sur l'une des chaînes faisant partie de l'ajout.

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

Ma méthode préférée est la suivante:

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

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

Vous pouvez y parvenir en ajoutant la méthode de jointure à NSArray avec une catégorie:

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

@[] c'est la définition courte pour NSArray, je pense que c'est la méthode la plus rapide pour concaténer des chaînes.

Si vous ne souhaitez pas utiliser la catégorie, utilisez directement la méthode componentsJoinedByString::

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

Essayez stringWithFormat:

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

Lorsque je traite souvent des chaînes, il est souvent plus facile de créer le fichier source ObjC++. Je peux ensuite concaténer std :: strings en utilisant la deuxième méthode indiquée dans la question.

std::string stdstr = [nsstr UTF8String];

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

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

Vous pouvez utiliser NSArray en tant que

NSString *string1=@"This"

NSString *string2=@"is just"

NSString *string3=@"a test"  

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

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

ou

vous pouvez utiliser

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

L'un ou l'autre de ces formats fonctionne dans XCode7 lorsque j'ai testé:

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

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

Pour une raison quelconque, vous n'avez besoin que du caractère opérateur @ sur la première chaîne du mélange.

Cependant, cela ne fonctionne pas avec l'insertion de variable. Pour cela, vous pouvez utiliser cette solution extrêmement simple à l'exception de l'utilisation d'une macro sur "cat" au lieu de "et".

1
Volomike

Pour tous les passionnés de l’objectif C qui en ont besoin dans un test d’interface utilisateur:

-(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

Imaginons que vous ne sachiez pas combien de chaînes il y a.

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

Dans 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"

De plus, vous pouvez utiliser l’opérateur += comme ci-dessous ...

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