Is there a quick method that gets the largest word from an array of words?
NSMutableArray wordlist
Something like the following should do the trick:
NSString *longest = nil;
for(NSString *str in wordlist) {
if (longest == nil || [str length] > [longest length]) {
longest = str;
}
}
I'm not aware of any simpler method.
You could use something like this example to sort an Array (but instead of the 'quality' sort in the example use a length sort on your strings) and then the longest string will be either at the top or at the end (depending on your sorting).
I don't know any objective C myself, but my solution would be to keep an integer 'longest' and a string 'longestWord' and initialise it to 0 and "". Then loop over the list and check if the current word is longer then the 'longest' value. If it is, store the new length and the current word. At the end of the loop, you have the longest word stored in the 'longestWord' variable.
Hope this helps
Related
I know I can check if a string contains uppercase letters but is there some built in function in Objective-C to check if all characters are uppercase letters? I want to avoid looping through each character to see if it contains a lowercase letter and then break out of the loop if it contains one as this takes up more memory and takes more time. Time is a constraint as I have to process thousands of strings.
An alternative approach that might appeal given your concerns: Use NSString's rangeOfCharactersFromSet: passing it NSCharacterSet's lowercaseLetterCharacterSet. If this finds anything then the string isn't all uppercase. It's a single line expression like the other current answers, but doesn't involve creating an uppercase copy of the string and works for all Unicode letters.
try this
NSString * myString;
[myString.uppercaseString isEqualToString:myString];
[your_string.uppercaseString isEqualToString:your_string];
If you need to process a lot of strings, especially long string may be following code will be faster
// In case you need process a lo of strings this set should be initialized before loop!
NSCharacterSet *set = [NSCharacterSet lowercaseLetterCharacterSet];
// check for allowed characters
BOOL isValid = ([string rangeOfCharacterFromSet:set].location == NSNotFound);
#implementation NSString (uppercaseOnly)
- (BOOL) allUpperCase {
return [self rangeOfCharacterFromSet:[[NSCharacterSet upperCaseLetterCharacterSet] invertedSet]].location == NSNotFound;
}
I have a list of contacts retrieved from Address book stored inside a MutableArray contactList. Each contact is an object which has properties like "contactName, contactImage.... etc".
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
//getAllContacts is a method which returns a Mutable array of Objects
self.contactList = [NSMutableArray arrayWithArray:[instance getAllContacts]];
//groupLetterToLoad could be "DEF"
for(int j=0; j<self.groupLetterToLoad.length;j++) {
//1st iteration D, 2nd iteration E and 3rd iteration F
NSString *testChar = [NSString stringWithFormat:#"%c",[self.groupLetterToLoad characterAtIndex:j]];
//check D,E,F with contact name property's first letter of the contact list array
for(int i=0;i<self.contactList.count;i++) {
NSString *firstChar =[[[self.contactList objectAtIndex:i] contactName] substringToIndex:1];
if([testChar isEqualToString: firstChar]) {
pos=i; //retrieve the index of the matched position
break;
}
}
if(pos!=-1) break;
}
});
Now this has two for loops (Time O(n^2)).. The disadvantage here is, if the groupLetterToLoad is "WXYZ", then comparison will start from W with A to W with Z.. How can I optimise it?
Ordering your array by contactName and performing a half interval search will reduce your complexity greatly if can avoid sorting every time you search (hint: keep [instance getAllContacts] sorted).
http://rosettacode.org/wiki/Binary_search#Objective-C - that's a starting point. you could replace the compare: with your first character comparison.
This isn't an algorithmic improvement, but the way you're handling characters is about the slowest way possible. If your group letters are really ASCII letters as you indicate, try this (I include the "if" in my answer because doing correct comparison of non-ASCII is really best left up to NSString):
1) Instead of using -substringToIndex to get the first character, use -characterAtIndex:0 and store a unichar
2) Instead of using +stringWithFormat:#"%c" to make a single character string, just use -characterAtIndex: and store it in a unichar
3) Instead of using -isEqualToString:, use == on the unichars
Unrelated, I'm pretty suspicious of the thread-safety of this. Are all those properties on self and instance you're accessing really not accessed on any other queue or thread?
I created an array called NSArray citiesList from a text file separating each object by the "," at the end of the line. Here is what the raw data looks like from the text file.
City:San Jose|County:Santa Clara|Pop:945942,
City:San Francisco|County:San Francisco|Pop:805235,
City:Oakland|County:Alameda|Pop:390724,
City:Fremont|County:Alameda|Pop:214089,
City:Santa Rosa|County:Sonoma|Pop:167815,
The citiesList array is fine (I can see count the objects, see the data, etc.) Now I want to parse out the city and Pop: in each of the array objects. I assume that you create a for loop to run through the objects, so if I wanted to create a mutable array called cityNames to populate just the city names into this array I would use this kind of for loop:
SMutableArray *cityNames = [NSMutableArray array];
for (NSString *i in citiesList) {
[cityNames addObject:[???]];
}
My question is what is what query should I use to find just the City: San Francisco from the objects in my array?
You can continue to use componentsSeparatedByString to divide up the sections and key/value pairs. Or you can use an NSScanner to read through the string parsing out the key/value pairs. You could use rangeOfString to find the "|" and then extract a range. So many options.
Many good suggestions in the answers here in case you really want to construct an algorithm to parse the string.
As an alternative to that, you can also look at it as a problem of declaring the structure of the data and then just have the system do the parsing. For a case like yours, regular expressions will do that nicely. Whether you prefer to do it one way or the other is largely a question of taste and coding standards.
In your specific case (if the city name is all you need to extract from the string), then also notice that there is a bit of a shortcut available that will turn it into a one-line solution: Match the whole string, define a single capture group and substitute that one to make a new string:
NSString *city = [i stringByReplacingOccurrencesOfString: #".*City:(.*?)\\|.*"
withString: #"$1"
options: NSRegularExpressionSearch
range: NSMakeRange(0, row.length)];
The variable i is the same that you have defined in your for-loop, i.e. a string containing a string representing a line in your input file:
City:San Jose|County:Santa Clara|Pop:945942,
I have added the initial .* to make the pattern robust to future new fields added to the rows. You can remove it if you don't like it.
The $1 in the substitution string represents the first capture group, i.e. the parenthesis in the regex pattern. In this specific case, the substring containing the city name. Had there been more capture groups, they would have been named $2-$9. You can check the documentation on NSRegularExpression and NSString if you want to know more.
Regular expressions are a topic all of their own, not confined to the Cocoa, although all platforms use regex implementations with their own idiosyncrasies.
You want to use componentsSeparatedByString: as below. (These lines do no error checking)
NSArray *fields = [i componentsSeparatedByString:#"|"];
NSString *city = [[[fields objectAtIndex:0] componentsSeparatedByString:#":"] objectAtIndex:1];
NSString *county = [[[fields objectAtIndex:1] componentsSeparatedByString:#":"] objectAtIndex:1];
If you can drop the keys, and a couple delimiters like this:
San Jose|Santa Clara|945942
San Francisco|San Francisco|805235
Oakland|Alameda|390724
Fremont|Alameda|214089
Santa Rosa|Sonoma|167815
Then you can simplify the code (still no error checking):
NSArray *fields = [i componentsSeparatedByString:#"|"];
NSString *city = [fields objectAtIndex:0];
NSString *county = [fields objectAtIndex:1];
for (NSString *i in citiesList) {
// Divide each city into an array, where object 0 is the name, 1 is county, 2 is pop
NSArray *stringComponents = [i componentsSeparatedByString:#"|"];
// Remove "City:" from string and add the city name to the array
NSString *cityName = [[stringComponents objectAtIndex:0] stringByReplacingCharactersInRange:NSMakeRange(0, 5) withString:#""];
[cityNames addObject:cityName];
}
I need to find a word or several words. With this method, however, I find also piece of word.
NSString *searchString = [NSString stringWithFormat:#"%#",searchField.text];
NSRange range = [textString rangeOfString : searchString];
if (range.location != NSNotFound) {
NSLog(#"textString = %#", textString);
}
I need the word / words exact
How can I do?
Thank you!
There are various ways of parsing/finding sub-strings in NSString:
NSString itself
NSRegularExpression. This would probably better suit your needs since you can tackle the scenario of surrounding white-spaces around words. Thus is won't return the cat from catapult when searching for cat.
NSScanner (most likely overkill for you needs)
... and they, of course, each have their PROs and CONs.
NSString has 9 methods grouped under "Finding Characters and Substrings". Methods such as:
-rangeOfString:
Finds and returns the range of the first occurrence of a given string within the receiver.
NSRegularExpression has 5 methods grouped under "Searching Strings Using Regular Expressions". Methods such as:
-numberOfMatchesInString: options: range:
Returns the number of matches of the regular expression within the specified range of the string.
It might also be useful to know about NSScanner, but this class would be more useful if you're parsing the string than simply looking for sub-parts.
What happens if you add a space at the end of the search string, like so:
NSString *searchString = [NSString stringWithFormat:#"%# ",searchField.text];
If the string from searchField.text already ends with a space, you would have to remove it.
This is not a perfect solution yet, for example you would not find the search string if it is at the end of a sentence. Instead what you could do is not adding the whitespace character, but instead look at the character after the hit and make sure that it is not a letter. For this, take a look at the class NSCharacterSet:
NSCharacterSet * letters = [NSCharacterSet letterCharacterSet];
if (![letters characterIsMember:[textString characterAtIndex:(range.location+searchString.length)]]) {
...
}
I'd like to let a string change letters to lowercase or uppercase randomly(in Xcode).
for example: "example" to "ExaMpLe" or "eXAMPle" or ExAmPlE" or something else like this randomly..
hot can i solve this?
thanks
You could either use the -uppercaseString and -lowercaseString methods on substrings, or use the toupper() and tolower() functions on characters. There's no way to simply filter a string; you'll want to use either an NSMutableString or a C array of characters.
See this question for how to get a random boolean value, which you can use to decide whether a character should be uppercase or lowercase.
NSString has both a lowercaseString and uppercaseString method. You can iterate over the characters in a string as a sequence of substrings, using some random source to call the appropriate lower/upper case on each of them, collecting the result. Something like...
NSMutableString result = [NSMutableString string];
for (NSUInteger i = 0; i < [myString length]; i++)
{
NSString *substring = [myString substringWithRange:NSMakeRange(i, 1)];
[result appendString:(rand() % 2) ? [substring lowercaseString]
: [substring uppercaseString]];
}
You may prefer a better source of entropy than rand, but it'll do for an example (don't forget to seed it if you use this case as is). If the strings are large, you can do it in-place on an NSMutableString.
You could break the word into an array of letters, and loop over this using a random number to determining case, after looping the array, simply stick the letters back together using NSMutableString.
NSString had a uppercaseString and lowercaseString methods you can use.