I want to concatenate some strings from variables if the variables are not nil. If they are nil, I don't want to include them. The following code works but is clunky and grows proportionately more complex with additional variables. Can anyone recommend a more elegant way to do this?
NSString *city = self.address.city== nil ? #"" : self.address.city;
NSString *state = self.address.state== nil ? #"" : self.address.state;
NSString *zip = self.address.zip== nil ? #"" : self.address.zip;
NSString *bestCity;
if (city.length>0&&state.length>0&&zip.length>0) {
bestCity = [NSString stringWithFormat: #"%# %# %#", city, state,zip];
}
else if (city.length>0&&state.length>0) {
bestName = [NSString stringWithFormat: #"%# %#", city,state];
}
else if (city.length>0&&zip.length>0) {
bestCity = [NSString stringWithFormat: #"%# %#", city,zip];
}
else if (city.length>0&&zip.length>0) {
bestCity = [NSString stringWithFormat: #"%# %#", city,zip];
}
else if (city.length>0) {
bestCity = [NSString stringWithFormat: #"%#", city];
}
else if (state.length>0) {
bestCity = [NSString stringWithFormat: #"%#", state];
}
else if (zip.length>0) {
bestCity = [NSString stringWithFormat: #"%#", zip];
}
else {
bestCity = #"";
}
I usually do something like:
NSMutableArray *bestCityArr = [#[] mutableCopy]; // [[NSMutableArray alloc] init];
if (city.length > 0)
[bestCityArr addObject:city];
if (state.length > 0)
[bestCityArr addObject:state];
if (zip.length > 0)
[bestCityArr addObject:zip];
NSString *bestCity = [bestCityArr componentsJoinedByString:#" "];
NSMutableArray *items = [[NSMutableArray alloc] init];
if (self.address.city)
[items appendObject:self.address.city];
if (self.address.state)
[items appendObject:self.address.state];
if (self.address.zip)
[items appendObject:self.address.zip];
NSString *bestCity = [items componentsJoinedByString:#" "];
This code may help you!
- (NSString *)concatenateString
{
NSMutableString *bestCity = [NSMutableString string];
NSString *city = self.address.city ?: #"";
[bestCity appendString:city];
NSString *state = self.address.state ?: #"";
if (state.length > 0) {
[bestCity appendString:#" "];
}
[bestCity appendString:state]];
NSString *zip = self.address.zip ?: #"";
if (zip.length > 0) {
[bestCity appendString:#" "];
}
[bestCity appendString:zip];
return bestCity.length > 0 ? bestCity : #"";
}
Related
I have NSMutableData array of bytes. I need to find item and then delete it.
my code:
NSArray *array = [[tunerButtonHostInfo objectForKey:#"local"] objectForKey:#"snPacket"];
NSMutableData *asciiData = [[NSMutableData alloc] init];
[asciiData appendData [#"\x00\x00\x02\x00\x00\x0e"dataUsingEncoding:NSASCIIStringEncoding]];
if(array != nil && ![array isKindOfClass:[NSNull class]] && [array isKindOfClass:[NSArray class]]) {
for(NSNumber *asciiCode in array) {
int asc = [asciiCode intValue];
if(asc == 0) {
NSString *string = #"\x00"; dataUsingEncoding:NSASCIIStringEncoding]];
}
else {
NSString *converted = [NSString stringWithFormat:#"%c", asc];
[asciiData appendData:[converted dataUsingEncoding:NSUTF8StringEncoding]];
}
}
NSLog(#"stringAsciiData"); //print asciiData
NSLog(#"%#", asciiData);
output of asciiData is:
00000200 000e6808 08680064 6c0b0367 6308c2b0 16
I need to find "c2" in the array and then remove it and shift remaining data in array to the left
Here is the modification to code to c2 . You can use append bytes method instead of converting to string and printing it back:
{
NSArray *array = #[#68,#0x08,#0x08,#68,#00,#64,#0x6c,#0x0b,#03,#67,#63,#0x08,#0xc2,#0xb0,#16];
NSMutableData *asciiData = [[NSMutableData alloc] init];
[asciiData appendData:[#"\x00\x00\x02\x00\x00\x0e"dataUsingEncoding:NSASCIIStringEncoding]];
if(array != nil && ![array isKindOfClass:[NSNull class]] && [array isKindOfClass:[NSArray class]]) {
for(NSNumber *asciiCode in array) {
Byte asc = [asciiCode intValue];
if(asc == 0) {
NSString *string = #"\x00";
[asciiData appendData:[string dataUsingEncoding:NSASCIIStringEncoding]];
}else if(asc != 0xc2) {
[asciiData appendBytes:&asc length:1];
}
}
NSLog(#"stringAsciiData"); //print asciiData
NSLog(#"%#", asciiData);
}
}
What would be the best way to transform NSStrings like these (mixed case)
#"Hello lorem ipsum";
#"i am a test";
to these (camel case without spaces)
#"helloLoremIpsum";
#"iAmATest";
Try this
Using For Loop
- (NSString *)camelCased:(NSString *)aString {
NSMutableString *result = [NSMutableString new];
NSArray *words = [aString componentsSeparatedByString: #" "];
for (NSUInteger i = 0; i < words.count; i++) {
if (i==0) {
[result appendString:([words[i] lowercaseString])];
}
else {
[result appendString:([words[i] capitalizedString])];
}
}
return result;
}
Using Block
- (NSString *)camelCasedUsingBlock:(NSString *)aString {
NSMutableArray *words = [[NSMutableArray alloc] init];
[[aString componentsSeparatedByString:#" "] enumerateObjectsUsingBlock:^(id anObject, NSUInteger idx, BOOL *stop) {
if (idx == 0) {
[words addObject:[anObject lowercaseString]];
}
else{
[words addObject:[anObject capitalizedString]];
}
}];
return [words componentsJoinedByString:#""];
}
NSLog(#"%#",[self camelCased:#"Hello lorem ipsum"]);//helloLoremIpsum
NSLog(#"%#",[self camelCased:#"i am a test"]);//iAmATest
It's overkill but TransformerKit has a bunch of NSValueTransformers that can be used, one is for camel casing. The relevant file is TTTStringTransformers.m if you want to build your own solution for lightness.
I'm using objective-c to parse a sentence here:
NSString *myString = #“Some words to form a string”;
Here is what I have so far:
NSMutableString *firstCharacters = [NSMutableString string];
NSMutableString *lastCharacters = [myString substringFromIndex:[myString length] - 1]
NSArray *arrayOfWords = [myString componentsSeparatedByString:[NSCharacterSet whitespaceCharacterSet]];
for (NSString *word in arrayOfWords) {
if ([word length] > 0) {
NSString *firstLetter = [word substringToIndex:1];
[firstCharacters appendString:lastCharacters];
and then I am really stumped at this point. I want to NSLog the recombined string so that it looks like this:
"S2e w3s to f2m a s3g"
Please try following code :
NSString *myString = #"Some words to form a string";
NSArray *wordsInSentence = [myString componentsSeparatedByString:#" "];
NSMutableArray *expectedResultArray = [[NSMutableArray alloc] init];
for (NSString *word in wordsInSentence) {
NSString *finalExpectedString = word;
if (word.length > 2) {
NSString *firstLetterInWord = [word substringToIndex:1];
NSString *lastLetterInWord = [word substringFromIndex:[word length] - 1];
finalExpectedString = [NSString stringWithFormat:#"%#%d%#", firstLetterInWord, (int)word.length - 2, lastLetterInWord];
}
[expectedResultArray addObject:finalExpectedString];
}
NSString *printString = [expectedResultArray componentsJoinedByString:#" "];
NSLog(#"Result : %#", printString);
This works fine if the textField is containing any text. But if the textField is empty, no objects are added.
How to tell this piece of code that if the textField is empty, all objects should be added to resultObjectsArray?
resultObjectsArray = [NSMutableArray array];
for(NSDictionary *object in allObjectsArray)
{
NSString *nameString = [NSString stringWithFormat:#"%#", [textField text]];
NSString *wineName = [wine objectForKey:#"Name"];
NSRange range = [wineName rangeOfString:nameString options:NSCaseInsensitiveSearch];
if ((range.location != NSNotFound))
[resultObjectsArray addObject:object];
}
resultObjectsArray = [NSMutableArray array];
NSString *nameString = [textField text];
for(NSDictionary *object in allObjectsArray)
{
if ([nameString length] > 0)
{
NSString *wineName = [wine objectForKey:#"Name"];
NSRange range = [wineName rangeOfString:nameString options:NSCaseInsensitiveSearch];
if ((range.location != NSNotFound))
[resultObjectsArray addObject:object];
}
else
{
[resultObjectsArray addObject:object];
}
}
Note that you don't need:
NSString *nameString = [NSString stringWithFormat:#"%#", [textField text]];
as
NSString *nameString = [textField text];
is sufficient. Also it won't change inside the for loop so can be initialised outside of it.
That's how the code ended up looking like using the answer from #trojanfoe. (I've excluded my other search criterias).
-(IBAction)searchButtonPressed:(id)sender{
BOOL textFieldIsEdited = NO;
if ([[textField text] length] > 0)
{
textFieldIsEdited = YES;
}
resultObjectsArray = [NSMutableArray array];
for(NSDictionary *wine in allObjectsArray)
{
BOOL nameMatch = YES;
if (textFieldIsEdited) {
NSString *wineName = [wine objectForKey:#"Name"];
NSString *nameString = [textField text];
NSRange range = [wineName rangeOfString:nameString options:NSCaseInsensitiveSearch];
if (range.location == NSNotFound) {
nameMatch = NO;
}
}
if ((nameMatch != NO))
[resultObjectsArray addObject:wine];
}
when I build and analize my application , am getting potential leak near the code [array1 release]...why its happening there..?thanks in advance
- (void) touchOnFeaturedCatalog
{
searchId == 2;
//featuredCatalogName = #"23064_Leeds2010";
//NSString *response = [ZoomCatalogAppDelegate getResponseFromServer:[NSString stringWithFormat:#"http://www.zoomcatalog.com/iphone/iphone.php?catalog=%#&iphone=Yes&pdf=No", featuredCatalogName]];
NSString *response = [ZoomCatalogAppDelegate getResponseFromServer:#"http://www.zoomcatalog.com/iphone/supplier.php"];
//NSString *response = [ZoomCatalogAppDelegate getResponseFromServer:#"http://test.atvescape.com/articles.php"];
//NSLog(#"Response = %#", response);
NSArray *array = [response componentsSeparatedByString:#"##"];
[array retain];
for(int i = 0; i < array.count; i++)
{
NSLog(#"Trying outer loop.... %d, %#, %#", i, [array objectAtIndex:i], featuredCatalogName);
NSArray *array4 = [featuredCatalogName componentsSeparatedByString:[array objectAtIndex:i]];
if(array4.count > 1)
{
response = [ZoomCatalogAppDelegate getResponseFromServer:[NSString stringWithFormat:#"http://www.zoomcatalog.com/iphone/catalog_search.php?tid2=%#&iphone=yes", [array objectAtIndex:i]]];
NSArray *array3= [response componentsSeparatedByString:#"<br>"];
//baseURL = [NSString stringWithFormat:#"%#", [array3 objectAtIndex:0]];
global_ContentString = [NSString stringWithFormat:#"%#", [array3 objectAtIndex:2]];//(searchId == 1 ? [array objectAtIndex:2] : ([array objectAtIndex: isLineNameSearch ? 2 : 1]))];
[global_ContentString retain];
// NSLog(#"baseURL = %#", global_ContentString);
NSArray *array1 = [global_ContentString componentsSeparatedByString:#"###"];
for(int j = 0; j < array1.count; j++)
{
NSArray *array2 = [[array1 objectAtIndex:j] componentsSeparatedByString:#"##"];
NSString *str = [NSString stringWithFormat:#"%#", [array2 objectAtIndex:0]];
str = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([str caseInsensitiveCompare:featuredCatalogName] == NSOrderedSame)
{
global_ContentString = [ZoomCatalogAppDelegate getResponseFromServer:[NSString stringWithFormat:#"http://www.zoomcatalog.com/iphone/iphone.php?catalog=%#&iphone=Yes&pdf=No", [array2 objectAtIndex:5]]];
baseURL = [NSString stringWithFormat:#"%#", [[global_ContentString componentsSeparatedByString:#"<br>"] objectAtIndex:0]];
//global_ContentString = [NSString stringWithFormat:#"%#", [[global_ContentString componentsSeparatedByString:#"<br>"] objectAtIndex:1]];
[global_ContentString retain];
[global_MainPageController presentModalViewController:global_FullPageController animated:YES];
//NSLog(#"$$$$$$$$$$$$$$$$$$$$$$ Catalog id = %# $$$$$$$$$$$$$$$$$$$$$$$$$$", [array2 objectAtIndex:5]);
//[array1 release];memory leak
return;
}
// NSLog(#"Trying inner loop.... %d, %#, %#", j, str, featuredCatalogName);
}
}
// if([[array objectAtIndex:i] com
}
[array release];
return;
}
sorry for all..
If you are only using an object locally (within the method in which it is created) you can autorelease it. Objects that are created or returned by convenience methods available until the end of the function call. Unless you need the objects elsewhere, I suggest ditching the retain calls. The rule of thumb is that whenever you call alloc, new, retain, or copy you mist release the object. However, if you use a convenience method, The returned object is autogenerate for you.
It seems that you call [global_ContentString retain]; but then fail to call a corresponding release.