I have scenarios in which I may have an NSString that contains several words, some of them duplicated. What I want to do is take a string that looks like:
One Two Three Three Three Two Two Two One One Two Three
and make it look like:
One Two Three
There may be times that the exact length of the original NSString is different as well. What I have so far is:
NSString *hereitis = #"First Second Third Second Third First First First";
NSArray *words = [hereitis componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSCountedSet *countedSet = [NSCountedSet setWithArray:words];
NSMutableArray *finalArray = [NSMutableArray arrayWithCapacity:[words count]];
for(id obj in countedSet) {
if([countedSet countForObject:obj] == 1) {
[finalArray addObject:obj];
}
}
NSString *string = [finalArray componentsJoinedByString:#" "];
NSLog(#"String%#", string);
This however, just returns String in my array, and not ANY of the words.
This can actually be done way less painlessly. NSSet doesn't allow duplicate entries. So, you can break the string into an array, and use that array to create the set. From there, all you have to do is convert back, and the dupes will be removed.
NSString *inputString = #"One Two Three Three Three Two Two Two One One Two Three";
NSSet *aSet = [NSSet setWithArray:[inputString componentsSeparatedByString:#" "]];
NSString *outputString = [aSet.allObjects componentsJoinedByString:#" "];
NSLog(#"___%#___",outputString); // Outputs "___One Two Three___"
You will get an array of strings then
for(id obj in countedSet) {
if([countedSet countForObject:obj] == 1) {
[finalArray addObject:obj];
}
}
After that you can use your words
NSLog(#"%#", finalArray[0]); //log 'One'
You can use KVC Collection Operators for this as well:
NSString *string = #"One Two Three Three Three Two Two Two One One Two Three";
NSArray *items = [string componentsSeparatedByString:#" "];
NSArray *uniqueItems = [items valueForKeyPath:#"#distinctUnionOfObjects.self"];
Related
I have an NSMutableArray that contains floats. I can display one float in a specific format or display all of them without formatting but I cannot figure out how to do both at once. I first wrap the float in an NSNumber so that it can be added to the array:
NSMutableArray *array = [[NSMutableArray alloc] init];
NSNumber *num = [NSNumber numberWithFloat:5.10f];
[array addObject:num];
NSNumberFormatter works for formatting the numbers to be displayed in a textView. Here is the code I used to do that:
for (NSNumber *aNumber in array) {
self.textView.text = [NSString stringWithFormat:#"%#"
[NSNumberFormatter localizedStringFromNumber:aNumber
numberStyle:NSNumberFormatterCurrencyStyle]];
}
The obvious problem here is the text is replaced with the number in the array each time the loop runs rather than listing all of them.
So, I did more research and found componentsJoinedByString:
self.textView.text = [NSString stringWithFormat:#"%#", [array componentsJoinedByString:#", "]];
This worked well to list them but lacked the formatting style: It displays, for example, 5.10 as 5.1 which I don't want. I tried to combine them somehow but it didn't work, and I also tried stringByAppendingString in the loop using the formatter but that was a mess that did not work at all.
You are replacing the text in the textView instead of appending..
for (NSNumber *aNumber in array) {
NSString *result = [NSNumberFormatter localizedStringFromNumber:aNumber
numberStyle:NSNumberFormatterCurrencyStyle];
if (aNumber == array.firstObject && !self.textView.text.length) {
self.textView.text = result;
}
else {
self.textView.text = [NSString stringWithFormat:#"%#, %#", self.textView.text, result];
}
}
I have a problem with NSString and NSMutableArray.
When I retrieve a string from mutable array ,it has more white spaces, and I don't understand why it's happening.
I'll explain, I have an array and populate it by query (using sqlite3):
NSMutableArray *fileNameAttached = [[NSMutableArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]];
and it's like this:
<__NSArrayM 0x15e233980>(
<__NSArrayM 0x15e26afd0>(
Allegato N. 1
)
)
When I retrieve the string Allegato N.1 with this code:
NSString *test = [NSString stringWithFormat:#"%#", [fileNameAttached objectAtIndex:0] ];
string test is like this:
(
"Allegato N. 1"
)
Why my string isn't only:
Allegato N.1
When I put it in a label it's not correct because contains () and white spaces.
The query for DB is:
NSString *query = [NSString stringWithFormat:#"SELECT fileName FROM Attach WHERE ID = '%#';",ticketID];
and works perfectly,in fact when I populate tableview cell it's OK. But I don't understand because my string test contains 3 line with more white spaces.
Please help Me.
Thank you and sorry for my english.
In your log there are two arrays.
(
(
Allegato N. 1
)
)
There are two round brackets thats means two array.
You are fetching data like NSString *test = [NSString stringWithFormat:#"%#", [fileNameAttached objectAtIndex:0] ];
That means first object of outer array so it is another array. so you need to do something like
NSArray *temp =[fileNameAttached objectAtIndex:0];
NSString *test = [NSString stringWithFormat:#"%#", [temp objectAtIndex:0] ];
I think you are using appcoda's DBManager class to do this. If it is so then you everytime got two array when load query.
Hope this will help :)
I'm doing an RSVP reading project app where it blinks words on the screen. You can set the word chunk size (how many words you want displayed at a time) to either 1, 2, or 3. I got it working for 1 word by having my paragraph in a string and doing:
[self.textInput componentsSeparatedByString:#" ";
This makes me an array of words that I can use to blink one word at a time. How would I be able to do this with displaying 2 words at a time? Is there a way I can use this function again to do it differently, or should I iterate over this word array and make a new one with 2 word strings?
Any help or advice would be greatly appreciated as to what the best practice would to get this done. Thanks.
just like keith said create an array
NSArray *allwordsArray = [self.textInput componentsSeparatedByString:#" "];
Now you got all the info you need. Meaning you got the array with every word in it. Now its just a matter of putting it together. (I haven't tested this code)
NSMutableArray *twoWordArray = [[NSMutableArray alloc] init];
int counter=0;
for (int i=0; i<[allwordsArray count]; i++)
{
if (counter >= [allwordsArray count]) break;
NSString *str1 = [NSString stringwithformat#"%#", [allwordsArray objectAtIndex:counter]];
counter++;
if (counter >= [allwordsArray count]) break;
NSString *str2 = [NSString stringwithformat#"%#", [allwordsArray objectAtIndex:counter]];
NSString *combinedStr = [NSString stringwithformat#"%# %#", str1,str2];
[twoWordArray addObject: combinedStr];
counter++;
}
You have broken the string into components, which is on the right track. You could then make a smaller array that only includes components until you reach the chunk size. The final step would be to rejoin the string.
NSArray *components = [self.textInput componentsSeparatedByString:#" "];
NSRange chunkRange = NSMakeRange(0, chunkSize);
NSArray *lessComponents = [components subarrayWithRange:chunkRange];
NSString *newString = [lessComponents componentsJoinedByString:#" "];
I am dividing string and and storing it in splitArray and want to return it.
But I am getting conflicting array on the first line
- (NSArray *)subdividingString:(NSString *)string {
NSArray *splitArray = [string componentsSeparatedByString:#" "];
return splitArray;
}
First: there is nothing wrong with the code, but you are most likely having another issue (e.g. where you call subdividingString:).
Second: You shouldn't introduce a method that is exactly doing what another one is doing already. Just use
NSString *mystring = #"some string";
NSArray *chunks = [mystring componentsSeparatedByString:#" "];
I want to scan NSString (case insensitive) to check whether all elements of an array contain in that String or not ?
Eg.
NSString *string1 = #"Java is pass by value : lets see how?";
NSString *string2 = #"Java is OOP Language";
NSArray *array = [[NSArray alloc] initWithObjects:#"Java",#"Pass",#"value", nil];
In this case string1 pass the test as it contain all keyword from array (i.e. Java,Pass,Value).
So, how can i achieve this functionality ?
I don't test it for speed, and it will fail on case-sensitive strings, but here's another solution (just in case)
NSArray *components = [string1 componentsSeparatedByString:#" "];
NSSet *textSet = [NSSet setWithArray:components];
NSSet *keywordsSet = [NSSet setWithArray:array];
BOOL result = [keywordsSet isSubsetOfSet:textSet];
Keep in mind that componentsSeparatedByString will tokenize very silly, like "how?" instead of "how" you need.
BOOL containsAll = YES;
for (NSString *test in array) {
if ([string1 rangeOfString:test].location == NSNotFound) {
containsAll = NO;
break;
}
}