get the first letter of each word in a string using objective-c - objective-c

Example of what I am trying to do:
String = "This is my sentence"
I am looking to get this as a result: "TIMS"
I am struggling with objective-c and strings for some reason

Naïve solution:
NSMutableString * firstCharacters = [NSMutableString string];
NSArray * words = [#"this is my sentence" componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
for (NSString * word in words) {
if ([word length] > 0) {
NSString * firstLetter = [word substringToIndex:1];
[firstCharacters appendString:[firstLetter uppercaseString]];
}
}
Note that this is kinda stupid about breaking up words (just going by spaces, which isn't always the best approach), and it doesn't handle UTF16+ characters.
If you need to handle UTF16+ characters, change the if() statement inside the loop to:
if ([word length] > 0) {
NSString * firstLetter = [word substringWithRange:[word rangeOfComposedCharacterSequenceAtIndex:0]];
[firstCharacters appendString:[firstLetter uppercaseString]];
}

You could always use the method cStringUsingEncoding: and just iterate the const char*. Or better, you could use the method getCharacters:
When you iterate, you just have to do a for loop and check if the previous character is the ' ' character and append it to your temporary variable. If you want it uppercase, just use uppercaseString at the end.
see apple doc for more information:
http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/getCharacters:range:
I also struggle with strings sometime, the function names are not really similar to other languages like c++/java for instance.

The shortest and faster way to enumerate through the string using below code
Swift
let fullWord = "This is my sentence"
var result = ""
fullWord.enumerateSubstrings(in: fullWord.startIndex..<fullWord.endIndex, options: .byWords) { (substring, _, _, _) in
if let substring = substring {
result += substring.prefix(1).capitalized }
}
print(result)
Output
TIMS

Related

Create NSArray of keywords starting/ending with % inside a string

I have a long string that contain keywords that start and end with the percent sign. E.g.:
My name is %user_username% and I live at %location_address%. You can
reach me at %user_phone%.
What method would I use to extract all strings that begin and end with % and put those into an NSArray so that I can replace them with their correct text representations?
Assuming that there are no % signs inside your strings of interest (e.g "a%ab%b%c"), you could use the componentsSeparatedByString: or componentsSeparatedByCharactersInSet: to get an array of strings separated by the % sign. From there, it's pretty easy to figure out which strings in that array are between the percent signs, and which are unnecessary.
I think internally though, those methods are likely implemented as something like a loop looking for %s. Maybe they parallelize the search on big strings, or use special knowledge of the internal structure of the string to make things faster -- those are the only ways I can see to speed up the search, assuming that you're stuck with keeping it all in a % delimited string (if speed is really an issue, then the answer is probably to use an alternative representation).
This is what I came up with that works:
- (NSArray *)replaceKeywords:(NSString *)keywordString {
NSString *start = #"%";
NSString *end = #"%";
NSMutableArray* strings = [NSMutableArray arrayWithCapacity:0];
NSRange startRange = [keywordString rangeOfString:start];
for( ;; ) {
if (startRange.location != NSNotFound) {
NSRange targetRange;
targetRange.location = startRange.location + startRange.length;
targetRange.length = [keywordString length] - targetRange.location;
NSRange endRange = [keywordString rangeOfString:end options:0 range:targetRange];
if (endRange.location != NSNotFound) {
targetRange.length = endRange.location - targetRange.location;
[strings addObject:[keywordString substringWithRange:targetRange]];
NSRange restOfString;
restOfString.location = endRange.location + endRange.length;
restOfString.length = [keywordString length] - restOfString.location;
startRange = [keywordString rangeOfString:start options:0 range:restOfString];
} else {
break;
}
} else {
break;
}
}
return strings;
}
I slightly modified the method from Get String Between Two Other Strings in ObjC

Parsing arithmetic expression for long numbers that need formatting

I am trying to make a simple calculator app. Currently, the app works perfectly. One problem: It's smart enough to change results into formatted numbers (800000 = 800,000), but not full expressions (200*600/21000 = 200*600/21,000).
I would like to be able to have a method that I could feed a string and get back a string of properly formatted numbers with operations still inside the string.
Example:
I feed the method 30000/80^2. Method gives back 30,000/80^2.
EDIT: People seem to be misunderstanding the question (Or it's possible I am misunderstanding the answers!) I want to be able to separate the numbers - 60000/200000 would separate into 60000 & 200000. I can do it from there.
Well, what's the problem? You obviously can parse the whole expression (you say calculator works), you can format single numbers (you say you can format results).
The only thing you need is to parse the expression, format all the numbers and recompose the expression...
EDIT: There is a simpler solution. For formatting, you don't need to parse the expression into a tree. You just have to find the numbers.
I suggest to create character set of all operators
NSCharacterSet* operators = [NSCharacterSet characterSetWithCharactersInString:#"+*-/^()"];
NSCharacterSet* whitespaces = [NSCharacterSet whitespaceCharacterSet];
Then split the expression using this set:
NSString* expression = [...];
NSMutableString* formattedExpression = [NSMutableString string];
NSRange numberRange = NSMakeRange(0, 0);
for (NSUInteger i = 0; i < expression.length; i++) {
unichar character = [expression characterAtIndex:i];
if ([whitespaces characterIsMember:character] || [operators characterIsMember:character]) {
if (numberRange.length > 0) {
NSString* number = [expression substringWithRange:numberRange];
NSString* formattedNumber = [self formatNumber:number];
[formattedExpression appendString:number];
numberRange.length = 0;
}
}
else if (numberRange.length == 0) {
numberRange.location = i;
numberRange.length = 1;
}
else {
numberRange.length++;
}
if ([operators characterIsMember:character]) {
[formattedExpression appendFormat:#"%C", character];
}
}
if (numberRange.length > 0) {
NSString* number = [expression substringWithRange:numberRange];
NSString* formattedNumber = [self formatNumber:number];
[formattedExpression appendString:number];
}
Note that this should work even for numbers prefixed by a sign. I am ignoring all whitespaces because if you want to have a pretty expression, you probably want to handle whitespaces differently (e.g. no space after (, space before +/-, space after - only if it's not a number sign...). In general, for handling spaces, parsing the expression into a tree would simplify matters. Also note that infix expressions are not unambiguous - that means that you should sometimes add parenthesis. However, that can't be done without parsing into a tree.
Look up NSNumberFormatter. Not only will that handle formatting of numbers, it will do so based on the user's locale.

Objective C How to detect one or multiple spaces in a NSString

I have seen one answer for my task, but I couldnt find it now.
I want to detect whether a string has empty word and contains at least "" or " " (two spaces" or more multiple spaces, OR not.
If not, I would add this to Nsmutablearray.
If yes with empty or at least one space, I would like it not to be written to mutablearray.
How to solve this?
EDIT 12 October 2011:
Guys, thank you.
Again I am sorry that I was unclear about my wish. I wanted to check if a string is empty or contains whitespaces without any character. I have posted my answer below.
Im not sure whether it is the most performant way of doing it but you could split your array and see whether the length is greater than 1:
if ([string componentsSeparatedByString:#" "].count > 1)
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html
if( bookmarked.length == 0 )
{
NSLog (#"not allowed: empty");
}
else if ([[bookmarked stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0)
{
NSLog (#"not allowed: whitespace(s)");
}
else
{
[bookmarklist addObject:bookmarked];
}
Depends if you're looking for ANY whitespace or just spaces. For spaces you can use:
if( [string length] == 0 ||
!NSEqualRanges( [string rangeofString:#" "],
NSMakeRange(NSNotFound, 0) ) )
{
// either the string is empty or we found a space
} else {
// we didn't find a space and the string is at least of length 1
}
If any whitespace, use the whitespace character set:
if( [string length] == 0 ||
!NSEqualRanges( [string rangeOfCharacterFromSet:
[NSCharacterSet whitespaceCharacterSet]],
NSMakeRange(NSNotFound, 0) ) )
{
// either the string is empty or we found a space
} else {
// we didn't find a space and the string is at least of length 1
}
Replace whitespaceCharacterSet with whitespaceAndNewlineCharacterSet if you like.
Look at the documentation for NSString.
Specifically, look under the section Finding Characters and Substrings for the method you want, probably you want to use – rangeOfString:options:range: multiple times.
Also, look under the section Replacing Substrings for the method you want, probably you want to use – stringByReplacingOccurrencesOfString:withString:options:range:
Take a look at the NSRegularExpression class and coding examples.
NSString *myString = #"ABC defa jh";
int spaceCount = [[myString componentsSeparatedByString:#" "] count] - 1;
if (!spaceCount) {
// Zero spaces, Do Something
} else if (spaceCount <= 2) {
// 1-2 spaces add this to NSMutableArray (although the wording about what you wanted to do in each case is confusing, so adjust for your needs)
} else {
// 3+ spaces, Do Not add this to NSMutableArray (adjust for your needs)
}

How to check if NSString begins with a certain character

How do you check if an NSString begins with a certain character (the character *).
The * is an indicator for the type of the cell, so I need the contents of this NSString without the *, but need to know if the * exists.
You can use the -hasPrefix: method of NSString:
Objective-C:
NSString* output = nil;
if([string hasPrefix:#"*"]) {
output = [string substringFromIndex:1];
}
Swift:
var output:String?
if string.hasPrefix("*") {
output = string.substringFromIndex(string.startIndex.advancedBy(1))
}
You can use:
NSString *newString;
if ( [[myString characterAtIndex:0] isEqualToString:#"*"] ) {
newString = [myString substringFromIndex:1];
}
hasPrefix works especially well.
for example if you were looking for a http url in a NSString, you would use componentsSeparatedByString to create an NSArray and the iterate the array using hasPrefix to find the elements that begin with http.
NSArray *allStringsArray =
[myStringThatHasHttpUrls componentsSeparatedByString:#" "]
for (id myArrayElement in allStringsArray) {
NSString *theString = [myArrayElement description];
if ([theString hasPrefix:#"http"]) {
NSLog(#"The URL is %#", [myArrayElement description]);
}
}
hasPrefix returns a Boolean value that indicates whether a given string matches the beginning characters of the receiver.
- (BOOL)hasPrefix:(NSString *)aString,
parameter aString is a string that you are looking for
Return Value is YES if aString matches the beginning characters of the receiver, otherwise NO. Returns NO if aString is empty.
As a more general answer, try using the hasPrefix method. For example, the code below checks to see if a string begins with 10, which is the error code used to identify a certain problem.
NSString* myString = #"10:Username taken";
if([myString hasPrefix:#"10"]) {
//display more elegant error message
}
Use characterAtIndex:. If the first character is an asterisk, use substringFromIndex: to get the string sans '*'.
NSString *stringWithoutAsterisk(NSString *string) {
NSRange asterisk = [string rangeOfString:#"*"];
return asterisk.location == 0 ? [string substringFromIndex:1] : string;
}
Another approach to do it..
May it help someone...
if ([[temp substringToIndex:4] isEqualToString:#"http"]) {
//starts with http
}
This might help? :)
http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/characterAtIndex:
Just search for the character at index 0 and compare it against the value you're looking for!
This nice little bit of code I found by chance, and I have yet to see it suggested on Stack. It only works if the characters you want to remove or alter exist, which is convenient in many scenarios. If the character/s does not exist, it won't alter your NSString:
NSString = [yourString stringByReplacingOccurrencesOfString:#"YOUR CHARACTERS YOU WANT TO REMOVE" withString:#"CAN either be EMPTY or WITH TEXT REPLACEMENT"];
This is how I use it:
//declare what to look for
NSString * suffixTorRemove = #"</p>";
NSString * prefixToRemove = #"<p>";
NSString * randomCharacter = #"</strong>";
NSString * moreRandom = #"<strong>";
NSString * makeAndSign = #"&amp;";
//I AM INSERTING A VALUE FROM A DATABASE AND HAVE ASSIGNED IT TO returnStr
returnStr = [returnStr stringByReplacingOccurrencesOfString:suffixTorRemove withString:#""];
returnStr = [returnStr stringByReplacingOccurrencesOfString:prefixToRemove withString:#""];
returnStr = [returnStr stringByReplacingOccurrencesOfString:randomCharacter withString:#""];
returnStr = [returnStr stringByReplacingOccurrencesOfString:moreRandom withString:#""];
returnStr = [returnStr stringByReplacingOccurrencesOfString:makeAndSign withString:#"&"];
//check the output
NSLog(#"returnStr IS NOW: %#", returnStr);
This one line is super easy to perform three actions in one:
Checks your string for the character/s you do not want
Can replaces them with whatever you like
Does not affect surrounding code
NSString* expectedString = nil;
if([givenString hasPrefix:#"*"])
{
expectedString = [givenString substringFromIndex:1];
}

Best way to split a string into tokens skipping escaped delimiters?

I'm receiving an NSString which uses commas as delimiters, and a backslash as an escape character. I was looking into splitting the string using componentsSeparatedByString, but I found no way to specify the escape character. Is there a built-in way to do this? NSScanner? CFStringTokenizer?
If not, would it be better to split the string at the commas, and then rejoin tokens that were falsely split (after inspecting them for a (non-escaped) escape character at the end) or looping through each character trying to find a comma, and then looking back one character to see if the comma is escaped or not (and then one more character to see if the escape character is escaped).
Now that I think about it, I would need to check that the amount of escape characters before a delimiter is even, because only then is the delimiter itself not being escaped.
If someone has a method that does this, I'd appreciate it if I could take a look at it.
I think the most straightforward method to do this would be to go through the string character by character as you suggest, appending into new string objects. You can follow two simple rules:
if you find a backslash, ignore but copy the next character (if exists) unconditionally
if you find a comma, end of that section
You could do this manually or use some of the functionality of NSScanner to help you (scanUpToCharactersFromSet:intoString:)
I would prefer to use a regular expression based parser to weed out the escape characters and then possibly doing a split operation (of some type) on the string.
Okay, (I hope) this is what wipolar suggested. It's the first implementation that works. I've just started with a non-GC-collected language, so please post a comment if you think this code can be improved, especially in the memory-management department.
- (NSArray *) splitUnescapedCharsFrom: (NSString *) str atChar: (char) delim withEscape: (char) esc
{
NSMutableArray * result = [[NSMutableArray alloc] init];
NSMutableString * currWord = [[NSMutableString alloc] init];
for (int i = 0; i < [str length]; i++)
{
if ([str characterAtIndex:i] == esc)
{
[currWord appendFormat:#"%c", [str characterAtIndex:++i]];
}
else if ([str characterAtIndex:i] == delim)
{
[result addObject:[NSString stringWithString:currWord]];
[currWord release];
currWord = [[NSMutableString alloc] init];
}
else
{
[currWord appendFormat:#"%c", [str characterAtIndex:i]];
}
}
[result addObject:[NSString stringWithString:currWord]];
[currWord release];
return [NSArray arrayWithArray:result];
}