iPhone - Splitting an NSString into char NSStrings - objective-c

I've got a 2d NSArray of {{"foo","food only only"}, {"bar","babies are rad"} ... } and I need to end up with 2 NSArrays: one of characters and one of the corresponding words. So #"f", #"o",#"b",#"a",#"r" and #"food",#"only",#"babies",#"are",#"rad" would be my two NSArray's of NSStrings.
So first, how do I get #"f",#"o",#"o" from #"foo"
And second how can I only keep the uniques? I'm guessing NSDictionary and only add if key is not there giving me #"f":#"food" #"o":#"only" then use getObjects:andKeys: to get two C arrays which I'll convert to NSArrays..
Based on the below answer I went with the following. I didn't actually use the NSMutableDict, I just added my letters to it to get the uniqueness check before creating my 2 output arrays:
unichar ch = [[arr objectAtIndex:0] characterAtIndex:i];
NSString *s = [NSString stringWithCharacters: &ch length: 1];
if (![dict objectForKey:s]) {
}

getCharacters will get you started with an array of characters: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/getCharacters:
You could cycle through and check for uniques after

If you want the individual characters of a string, try -characterAtIndex:. That will get you them as the unichar primitive type, which you can then wrap in NSString like so:
unichar ch = ...;
NSString *chString = [NSString stringWithCharacters: &ch length: 1];
To keep uniques, you can store objects in an NSMutableSet, though it will not preserve the order in which objects are added to it.

Related

Conversion from NSString to Hex

i am new in this field and i was working on a conversion of NSString to Hex and have been stuck into it. My String lets suppose is 1,FF,F8 now how can i convert that into hex numbers like 0x01,0x0FF and 0x0F8
First step would be to split the string containing "1,FF,F8" into three strings containing the separate hex values, "1", "FF", "F8".
NSString *hexString = #"1,FF,F8";
NSArray *hexValues = [hexString componentsSeparatedByString:#","];
As for the conversion from NSString to hex, I'm not quite sure what exactly you want.
If you just want to add on a "0x0" to the beginning of the hex values, you can just do:
NSMutableArray *formattedHexValues = [NSMutableArray array];
for(NSString *hexValue in hexValues) {
[formattedHexValues addObject:[NSString stringWithFormat:#"0x0%#", hexValue]];
}
If you want to actually get the integer value of the hex string, do this:
for(NSString *hexString in formattedHexValues) {
unsigned int value;
[[NSScanner scannerWithString:hexString] scanHexInt:&value];
NSLog(#"The value is %d", value);
}
Typed this out in the browser so there might be a syntax mistake or two, but it generally should work fine.

Sort ignoring punctuation (Objective-C)

I am trying to sort an iOS UITableView object. I am currently using the following code:
// Sort terms alphabetically, ignoring case
[self.termsList sortUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
This sorts my list, whist ignoring case. However, it would be nice to ignore punctuation as well. For example:
c.a.t.
car
cat
should be sorted as follows:
car
c.a.t.
cat
(It doesn't actually matter which of the two cats (cat or c.a.t.) comes first, so long as they're sorted next to one another).
Is there a simple method to get around this? I presume the solution would involve extracting JUST the alphanumeric characters from the strings, then comparing those, then returning them back to their former states with the non-alphanumeric characters included again.
In point of fact, the only characters I truly care about are periods (.) but if there is a solution that covers all punctuation easily then it'd be useful to know.
Note: I asked this exact same question of Java a month ago. Now, I am creating the same solution in Objective-C. I wonder if there are any tricks available for the iOS API that make this easy...
Edit: I have tried using the following code to strip punctuation and populate another array which I sort (suggested by #tiguero). However, I don't know how to do the last step: to actually sort the first array according to the order of the second. Here is my code:
NSMutableArray *arrayWithoutPunctuation = [[NSMutableArray alloc] init];
for (NSString *item in arrayWithPunctuation)
{
// Replace hyphens/periods with spaces
item = [item stringByReplacingOccurrencesOfString:#"-" withString:#" "]; // ...hyphens
item = [item stringByReplacingOccurrencesOfString:#"." withString:#" "]; // ...periods
[arrayWithoutPunctuation addObject:item];
}
[arrayWithoutPunctuation sortUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
This provides 'arrayWithoutPunctuation' which is sorted, but of course doesn't contain the punctuation. This is no good, since, although it is now sorted nicely, it no longer contains punctuation which is crucial to the array in the first place. What I need to do is sort 'arrayWithPunctuation' according to the order of 'arrayWithoutPunctuation'... Any help appreciated.
You can use a comparison block on an NSArray and your code will look like the following:
NSArray* yourStringList = [NSArray arrayWithObjects:#"c.a.t.", #"car", #"cat", nil];
NSArray* yourStringSorted = [yourStringList sortedArrayUsingComparator:^(id a, id b){
NSString* as = (NSString*)a;
NSString* bs = (NSString*)b;
NSCharacterSet *unwantedChars = [NSCharacterSet characterSetWithCharactersInString:#"\\.:',"];
//Remove unwanted chars
as = [[as componentsSeparatedByCharactersInSet: unwantedChars] componentsJoinedByString: #""];
bs = [[as componentsSeparatedByCharactersInSet: unwantedChars] componentsJoinedByString: #""];
// make the case insensitive comparison btw your two strings
return [as caseInsensitiveCompare: bs];
}];
This might not be the most efficient code actually one other option would be to iterate on your array first and remove all unwanted chars and use a selector with the caseInsensitiveCompare method:
NSString* yourStringSorted = [yourStringList sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
This is a bit cleaner, and a bit more efficient:
NSArray* strings = #[#".....c",#"a.",#"a",#"b",#"b...",#"a..,"];
NSArray* sorted_strings = [strings sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSString* a = [obj1 stringByTrimmingCharactersInSet:[NSCharacterSet punctuationCharacterSet]];
NSString* b = [obj2 stringByTrimmingCharactersInSet:[NSCharacterSet punctuationCharacterSet]];
return [a caseInsensitiveCompare:b];
}];
For real efficiency, I'd write a compare method that ignores punctuation, so that no memory allocations would be needed just to compare.
My solution would be to group each string into a custom object with two properties
the original string
the string without punctuation
...and then sort the objects based on the string without punctuation.
Objective C has some handy ways to do that.
So let's say we have two strings in this object:
NSString *myString;
NSString *modified;
First, add your custom objects to an array
NSMutableArray *myStrings = [[NSMutableArray alloc] init];
[myStrings addObject: ...];
Then, sort the array by the modified variable using the handy NSSortDescriptor.
//You can specify the variable name to sort by
//Sorting is done according to the locale using localizedStandardCompare
NSSortDescriptor *mySortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"modified" ascending:YES selector:#selector(localizedStandardCompare:)];
[myStrings sortedArrayUsingDescriptors:#[ mySortDescriptor ]];
Voila! Your objects (and strings) are sorted. For more info on NSSortDescriptor...

Get Unicode point of NSString and put that into another NSString

What's the easiest way to get the Unicode value from an NSString? For example,
NSString *str = "A";
NSString *hex;
Now, I want to set the value of hex to the Unicode value of str (i.e. 0041)... How would I go about doing that?
The unichar type is defined to be a 16-bit unicode value (eg, as indirectly documented in the description of the %C specifier), and you can get a unichar from a given position in an NSString using characterAtIndex:, or use getCharacters:range: if you want to fill a C array of unichars from the NSString more quickly than by querying them one by one.
NSUTF32StringEncoding is also a valid string encoding, as are a couple of endian-specific variants, in case you want to be absolutely future proof. You'd get a C array of those using the much more longwinded getBytes:maxLength:usedLength:encoding:options:range:remainingRange:.
EDIT: so, e.g.
NSString *str = #"A";
NSLog(#"16-bit unicode values are:");
for(int index = 0; index < [str length]; index++)
NSLog(#"%04x", [str characterAtIndex:index]);
You can use
NSData * u = [str dataUsingEncoding:NSUnicodeStringEncoding];
NSString *hex = [u description];
You may replace NSUnicodeStringEncoding by NSUTF8StringEncoding, NSUTF16StringEncoding (the same as NSUnicodeStringEncoding) or NSUTF32StringEncoding, or many other values.
See here
for more

How to append NSString wiht number?

I'm new in Cocoa.
I have NSString - (e.g) MUSIC . I want to add some new NSString in Array,
And want to check something like this
if MUSIC already contained in Array, add Music_1 , after Music_2 and so on.
So I need to be able read that integer from NSString, and append it +1 .
Thanks
Use
NSString *newString = [myString stringByAppendingString:[NSString stringWithFormat:#"_%i", myInteger]];
if myString is "music", newString will be "music_1" or whatever myInteger is.
EDIT: I seem to have gotten the opposite meaning from the other answer provided. Can you maybe clarify what it is you are asking exactly?
Check it out:
NSMutableArray *array = [NSMutableArray arrayWithObjects:#"123", #"qqq", nil];
NSString *myString = #"MUSIC";
NSInteger counter = 0;
if ([array containsObject:myString]){
NSString *newString = [NSString stringWithFormat:#"%#_%d", myString, ++counter];
[array addObject:newString];
}
else
[array addObject:myString];
For checking duplicate element in Array you can use -containsObject: method.
[myArray containsObject:myobject];
If you have very big array keep an NSMutableSet alongside the array.Check the set for the existence of the item before adding to the array. If it's already in the set, don't add it. If not, add it to both.
If you want unique objects and don't care about insertion order, then don't use the array at all, just use the Set. NSMutableSet is a more efficient container.
For reading integer from NSString you can use intValue method.
[myString intValue];
For appending string with number you can use - (NSString *)stringByAppendingString:(NSString *)aString or - (NSString *)stringByAppendingFormat:(NSString *)format ... method.
Here's how you convert a string to an int
NSString *myStringContainingInt = #"5";
int myInt = [myStringContainingInt intValue];
myInt += 1;
// So on...

How to get a single NSString character from an NSString

I want to get a character from somewhere inside an NSString. I want the result to be an NSString.
This is the code I use to get a single character at index it:
[[s substringToIndex:i] substringToIndex:1]
Is there a better way to do it?
This will also retrieve a character at index i as an NSString, and you're only using an NSRange struct rather than an extra NSString.
NSString * newString = [s substringWithRange:NSMakeRange(i, 1)];
If you just want to get one character from an a NSString, you can try this.
- (unichar)characterAtIndex:(NSUInteger)index;
Used like so:
NSString *originalString = #"hello";
int index = 2;
NSString *theCharacter = [NSString stringWithFormat:#"%c", [originalString characterAtIndex:index-1]];
//returns "e".
Your suggestion only works for simple characters like ASCII. NSStrings store unicode and if your character is several unichars long then you could end up with gibberish. Use
- (NSRange)rangeOfComposedCharacterSequenceAtIndex:(NSUInteger)index;
if you want to determine how many unichars your character is. I use this to step through my strings to determine where the character borders occur.
Being fully unicode able is a bit of work but depends on what languages you use. I see a lot of asian text so most characters spill over from one space and so it's work that I need to do.
NSMutableString *myString=[NSMutableString stringWithFormat:#"Malayalam"];
NSMutableString *revString=#"";
for (int i=0; i<myString.length; i++) {
revString=[NSMutableString stringWithFormat:#"%c%#",[myString characterAtIndex:i],revString];
}
NSLog(#"%#",revString);