NSString to NSArray and iterate - xcode

I have a code that creates an NSString and separates value with a comma. What I need to do is take that string, convert it to a NSArray and separate each value from the NSString between the commas, then iterate through each one. The code below returns the array as a single string
NSString *emails = #"testemail#gmail.com, testemail2#gmail.com";
NSArray *listItems = [emails componentsSeparatedByString:#", "];
for (int i = 0; i < [listItems count]; i++) {
NSString *address = (NSString*) [listItems objectAtIndex:i];
NSLog (#"ADDRESS: %#", address);
The Log shows the response testemail#gmail.com, testemail2#gmail.com when I want it to separate each one individually. Should this be an NSMutableArray instead?

The code is correct. You'll get two (separate) lines starting with ADDRESS:
But nowadays (actually since 2009!) it's highly recommended to use Fast Enumeration if the loop index is not needed
NSString *emails = #"testemail#gmail.com, testemail2#gmail.com";
NSArray *listItems = [emails componentsSeparatedByString:#", "];
for (NSString *email in listItems) {
NSLog(#"ADDRESS: %#", email);
}

Related

How to use "valueforkey"?

I'm trying to do the following - I have an Array in which some strings are stored. These strings shall be used to call an NSArray. An example will clarify what I'm trying to do:
This is the working code that I'm trying to achieve ("briefing0" is of type NSArray):
NSString *path = [docsDir stringByAppendingPathComponent:[briefing0 objectAtIndex:indexPath.row]];
This is the "same" code that I'm trying to use:
int i = 0;
NSString *path = [docsDir stringByAppendingPathComponent:[(NSArray *)[NSString stringWithFormat:#"briefing%d", i] objectAtIndex:indexPath.row]];
Any ideas?
Thanks in advance!
Tom
Assuming that briefing0 is actually a property, then yes, this is possible (and not uncommon) in ObjC via KVC.
int i = 0;
NSString *prop = [NSString stringWithFormat:#"briefing%d", i];
NSArray *array = [self valueForKey:prop];
NSString *value = [array objectAtIndex:indexPath.row];
... etc. ...
-valueForKey: is the piece you're looking for. Note that this will throw an exception if you construct a key that does not exist, and so must be used with extreme care.

xcode split NSString to other NSStrings

{"Title":"Chatroom","Year":"2010","Rated":"R","Released":"11 Aug 2010","Genre":"Drama, Thriller","Director":"Hideo Nakata","Writer":"Enda Walsh, Enda Walsh","Actors":"Aaron Johnson, Imogen Poots, Matthew Beard, Hannah Murray","Plot":"A group of teenagers encourage each other's bad behavior.","Poster":"http://ia.media-imdb.com/images/M/MV5BMjE0MjM5MDM2MF5BMl5BanBnXkFtZTcwMzg1MzY0Mw##._V1._SX320.jpg","Runtime":"1 hr 37 mins","Rating":"5.3","Votes":"1000","ID":"tt1319704","Response":"True"}
i get this data with nsstring and my question is how to split data that , separates to another nsstrings, but i want to make as commas so much nsstrings
Use the following
NSString *str; //Pass your string to str
NSArray *array = [str componentsSeparatedByString:#","];
for(int i = 0; i < [array count]; i++) {
// Here just take strings one by one
}
NSString *string= //pass the string whatever you want.
NSArray *splitArray = [string componentsSeparatedByString:#","]; //it separates the string and store it in the different different indexes.
Ex:
NSString *str= #"one,two,three";
NSArray *array = [str componentsSeparatedByString:#","]; //it separates the string and store it in the different different indexes(one is at index 0 ,two is at index 1 and three is at index 2).

Check for String within a String

I'm trying to compare two strings
NSString strOne = #"Cat, Dog, Cow";
NSString strTwo = #"Cow";
How do I determine if strOne contains strTwo
Try using rangeOfString:
NSRange result = [strOne rangeOfString:strTwo];
From the documentation:
Returns an NSRange structure giving the location and length in the receiver of the first occurrence of aString. Returns {NSNotFound, 0} if aString is not found or is empty (#"").
For anyone needing the code to check is a string exists within a string, here's my code thanks to fbrereto. This example checks to see if any string contained in an array of strings (stringArray) can be found within a string (myString):
int count = [stringArray count];
for (NSUInteger x = 0; x < count; ++x) {
NSRange range = [self.myString rangeOfString:[stringArray objectAtIndex:x]];
if (range.length > 0) {
// A match has been found
NSLog(#"string match: %#",[stringArray objectAtIndex:x]);
}
}
I believe this is the correct syntax for checking if the range exists (correcting response from Kendall):
range.location != NSNotFound
Gradually straying off topic, but I always explode my strings, which would mean just exploding it using your search string as a key and you can use the array count to see how many instances you have.
Just incase anyone is coming from a code language that uses "explode" to blow a string up into an array like me, I found writing my own explode function tremendously helpful, those not using "explode" are missing out:
- (NSMutableArray *) explodeString : (NSString *)myString key:(NSString*) myKey
{
NSMutableArray *myArray = [[NSMutableArray alloc] init];
NSRange nextBreak = [myString rangeOfString:myKey];
while(nextBreak.location != NSNotFound)
{
[myArray addObject: [myString substringToIndex:nextBreak.location]];
myString = [myString substringFromIndex:nextBreak.location + nextBreak.length];
nextBreak = [myString rangeOfString:myKey];
}
if(myString.length > 0)
[myArray addObject:myString];
return myArray;
}
works like this:
[self explodeString: #"John Smith|Age: 37|Account Balance: $75.00" key:#"|"];
which will return this array:
[#"John Smith", #"Age: 37", #"Account Balance: $75.00"];
This lets you quickly pull out a specific value in a tight space, Like if you have a client and you want to know how much money he has:
[[self explodeString: clientData key: pipe] objectAtIndex: 1];
or if you wanted specifically the dollar amount as a float:
[[[self explodeString: [[self explodeString: clientData key: pipe] objectAtIndex: 1] key: #": "] objectAtIndex: 2] floatValue];
anyway I find arrays way easier to work with and more flexible, so this is very helpful to me. Additionally with a little effort you could make an "explodable string" data type for your private library that lets you treat it like a string or return an index value based on the key
ExplodableString *myExplodableString;
myExplodableString.string = #"This is an explodable|string";
NSString *secondValue = [myExplodableString useKey: #"|" toGetValue: index];

How to sort NSMutableArray of NSMutableDictionary?

I have NSMutableArray of NSMutableDictionary(NSString objects). One of NSString object is actually a date, and i need to sort NSMutableArray based on that date and I don't want it to sort dates as strings. How can i make it?
If I understand correctly, your array contains dictionaries that contain strings and you want to sort on those strings... as dates. Something like this perhaps:
[someArray sortWithOptions: 0 usingComparator: ^(id inObj1, id inObj2) {
NSDate *date1 = [NSDate dateWithString: [inObj1 objectForKey: #"dateString"]];
NSDate *date2 = [NSDate dateWithString: [inObj2 objectForKey: #"dateString"]];
return [date1 compare: date2];
}];
You will need to use the sortedArrayUsingFunction:context: method. For example:
NSInteger comparator( NSDictionary *d1, NSDictionary *d2, void *context )
{
return [[d1 objectForKey:#"date"] compare:[d2 objectForKey:#"date"]];
}
// In some method:
NSArray *sortedArray = [array sortedArrayUsingFunction:comparator context:nil];
Note: This is not tested.

NSArray to Core Data items

I have an method that reads an xml file and stores the xml nodes at a certain XPath-path in an NSArray called *nodes. What I want to do is take each one of the items in the array and add it to a core data entity called Category with the attribute of "name".
I have tried a number of different ways of creating the entity but I'm not sure about the correct way to do this effectively. This is the code used to create the NSArray, any ideas on how to implement this? (ignore the NSError, I will fix this in the final version)
- (IBAction)readCategories:(id)sender
{
NSString *xmlString = [resultView string];
NSData *xmlData = [xmlString dataUsingEncoding: NSASCIIStringEncoding];
NSXMLDocument *xmlDoc = [[NSXMLDocument alloc] initWithData:xmlData options:nil error:nil];
//XPath
NSError *err=nil;
NSArray *nodes = [xmlDoc nodesForXPath:#"//member[name='description']/value/string" error:&err];
}
EDIT - My loop code
NSArray *nodes = [xmlDoc nodesForXPath:#"//member[name='description']/value/string" error:&err];
int arrayCount = [nodes count];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSXMLElement *categoryEl;
NSString *new = [catArrayController newObject];
int i;
for (i = 0; i < arrayCount; i++)
{
[categoryEl = [nodes objectAtIndex:i]];
[new setValue:[categoryEl stringValue] forKey:#"name"];
[catArrayController addObject:new];
}
[pool release];
Here's how I'd write it:
for (NSXMLElement *categoryElement in nodes) {
NSManagedObject *newObject = [catArrayController newObject];
[newObject setValue:[categoryElement stringValue] forKey:#"name"];
[catArrayController addObject:newObject];
[newObject release];
}
First, I'm using the Objective-C 2.0 for-each syntax. This is simpler than using index variables. I eliminated i and arrayCount.
Next, I took out your NSAutoreleasePool. None of the objects in the loop are autoreleased, so it had no effect. (The newObject method returns a retained object which is, by convention, what methods with the word new in their name do) This is also why I release newObject after adding it to the array controller. Since I'm not going to be using it any more in this method, I need to release it.
Also, you had defined new (which I renamed newObject) as an NSString. Core Data objects are always either an instance of NSManagedObject or a subclass of NSManagedObject.
Your line [categoryEl = [nodes objectAtIndex:i]] won't compile. That's because the bracket syntax is used to send a message to an object. This is an assignment statement, so the bracket syntax is not needed here. (This line is also not necessary any more because of I've changed the loop to use the for-each syntax) But, for future reference, categoryEl = [nodes objectAtIndex:i]; would have worked.
What part are you having trouble with? There shouldn't be much more to it than looping through the array, creating a new managed object for each entry, and setting the correct attributes. You can create the managed object with NSEntityDescription's -insertNewObjectForEntityForName:inManagedObjectContext: method.

Resources