Split an NSString in Objective-C with no delimiter [duplicate] - ios

This question already has answers here:
Extract characters from NSString object
(3 answers)
Closed 9 years ago.
I know there are several answers on splitting strings using componentsSeparatedByString:, but what if the string has no delimiter. using #"", doesn't work.
NSString *str = #"ABCDE";
NSArray *arr = [str componentsSeparatedByString:#""];
NSLog(#"%#", arr)
==> ABCDE
What I want is -
==> (A,B,C,D,E)
So that I can access each character. Thanks!

The most reliable technique is to use -[NSString enumerateSubstringsInRange:options:usingBlock:] with the NSStringEnumerationByComposedCharacterSequences option.
NSMutableArray* array = [NSMutableArray array];
[str enumerateSubstringsInRange:NSMakeRange(0, str.length)
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop){
[array addObject:substring];
}];

Either use [string characterAtIndex:i]; in a for loop or
- (NSString *)substringWithRange:(NSRange)aRange in a loop.
NSMutableArray *arr = [[NSMutableArray alloc] init];
for (int i = 0; i < string.length; i++)
{
unsigned int character = [string characterAtIndex:i];
[arr addObject:[NSString stringWithFormat:#"%C",character]];
}

Related

How to remove dots only from starting of string [duplicate]

This question already has answers here:
Swift: Remove specific characters of a string only at the beginning
(6 answers)
Closed 5 years ago.
My string text is Like -
1) .....bla ..bla...
2)...bla.. bla…bla.
3).bla.. bla…bla.
dots are not static.I want to remove dots only from starting. not All dots
I have tried with this
NSString *newString = [myString stringByReplacingOccurrencesOfString:#"." withString:#""];
but this is removing all dots.
try this.
NSString* regex = #"^\\.*";
NSString* input = #"....abc..z";
NSString* output = [input stringByReplacingOccurrencesOfString:regex withString:#"" options:NSRegularExpressionSearch range: [input rangeOfString:input]];
var test = "...abc";
while test.hasPrefix(".") {
test.remove(at: test.startIndex)
}
//test variable will have dots removed at the start.
Try this.
Try this:
NSString *str = #"...Videt...IDL";
__block NSInteger loc = 0;
[str enumerateSubstringsInRange:NSMakeRange(0, str.length) options:NSStringEnumerationByWords usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
loc = substringRange.location;
*stop = YES;
}];
NSString *convStr = [str substringFromIndex:loc];
NSLog(#"%#", convStr);
NSString *str = #"....bla .... bla..... bla";
NSCharacterSet *charSet = [NSCharacterSet letterCharacterSet];
int letterNO = 0;
for (int i =0; i<str.length; i++)
{
NSString *letter = [NSString stringWithFormat:#"%c",[str characterAtIndex:i]];
if ([letter rangeOfCharacterFromSet:charSet].location != NSNotFound)
{
letterNO = i;
break;
}
}
NSString * newString = [str substringFromIndex:letterNO];
NSLog(#"newString %#",newString);

how to convert NSString to NSArray [duplicate]

This question already has answers here:
Comma-separated string to NSArray in Objective-C
(2 answers)
Closed 8 years ago.
I have a string like
NSString* str = #"[90, 5, 6]";
I need to convert it to an array like
NSArray * numbers = [90, 5 , 6];
I did a quite long way like this:
+ (NSArray*) stringToArray:(NSString*)str
{
NSString *sep = #"[,";
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:sep];
NSArray *temp=[str componentsSeparatedByCharactersInSet:set];
NSMutableArray* numbers = [[NSMutableArray alloc] init];
for (NSString* s in temp) {
NSNumber *n = [NSNumber numberWithInteger:[s integerValue]];
[numbers addObject:n];
}
return numbers;
}
Is there any neat and quick way to do such conversion?
Thanks
First remove the unwanted characters from the string, like white spaces and braces:
NSString* str = #"[90, 5, 6]";
NSCharacterSet* characterSet = [[NSCharacterSet
characterSetWithCharactersInString:#"0123456789,"] invertedSet];
NSString* newString = [[str componentsSeparatedByCharactersInSet:characterSet]
componentsJoinedByString:#""];
You will have a string like this: 90,5,6. Then simply split using the comma and convert to NSNumber:
NSArray* arrayOfStrings = [newString componentsSeparatedByString:#","];
NSMutableArray* arrayOfNumbers = [NSMutableArray arrayWithCapacity:arrayOfStrings.count];
for (NSString* string in arrayOfStrings) {
[arrayOfNumbers addObject:[NSDecimalNumber decimalNumberWithString:string]];
}
Using the NSString category from this response it can be simplified to:
NSArray* arrayOfStrings = [newString componentsSeparatedByString:#","];
NSArray* arrayOfNumbers = [arrayOfStrings valueForKey: #"decimalNumberValue"];
NSString* str = #"[90, 5, 6]";
NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:#"[] "];
NSArray *array = [[[str componentsSeparatedByCharactersInSet:characterSet]
componentsJoinedByString:#""]
componentsSeparatedByString:#","];
Try like this
NSArray *arr = [string componentsSeparatedByString:#","];
NSString *newSTR = [str stringByReplacingOccurrencesOfString:#"[" withString:#""];
newSTR = [newSTR stringByReplacingOccurrencesOfString:#"]" withString:#""];
NSArray *items = [newSTR componentsSeparatedByString:#","];
You can achieve that using regular expression 
([0-9]+)
NSError* error = nil;
NSString* str = #"[90, 5, 6]";
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:#"([0-9]+)" options:0 error:&error];
NSArray* matches = [regex matchesInString:str options:0 range:NSMakeRange(0, [str length])];
Then you have a NSArray of string, you just need to iterate it and convert the strings to number and insert them into an array.

How to fetch the last word from textfield [duplicate]

This question already has answers here:
Getting the last word of an NSString
(7 answers)
Closed 8 years ago.
I have the following text in the text field
The Taj, Restraint, Renovation, Catch
How to get the Catch word alone from the text field.
NSString *str = #"The Taj, Restraint, Renovation, Catch";
NSString *lastWord = [[str componentsSeparatedByString:#","] lastObject];
Try this
NSString *myString = #"Taj, Restraint, Renovation, Catch" ;
__block NSString *lastWord = nil;
[myString enumerateSubstringsInRange:NSMakeRange(0, myString.length) options:(NSStringEnumerationByWords | NSStringEnumerationReverse) usingBlock:^(NSString *substring, NSRange subrange, NSRange enclosingRange, BOOL *stop) {
lastWord = substring;
*stop = YES;
}];

How do I count the occurrences of ALL characters of a string?

I am trying to find the number of times each character in a string is used. for example, in the string "wow" I would like to count the number of times the character "w" is used and the number of times the character "o" is used. I would then like to add these characters to an NSMutableArray. Is there a programmatic way to count the number of times all specific characters are used? To get the number of occurrences of ALL characters in an NSString? Or would I have to go through the process of counting the occurrences of each individual character separately?
See iOS - Most efficient way to find word occurrence count in a string
NSString *string = #"wow";
NSCountedSet *countedSet = [NSCountedSet new];
[string enumerateSubstringsInRange:NSMakeRange(0, [string length])
options:NSStringEnumerationByComposedCharacterSequences | NSStringEnumerationLocalized
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop){
// This block is called once for each word in the string.
[countedSet addObject:substring];
// If you want to ignore case, so that "this" and "This"
// are counted the same, use this line instead to convert
// each word to lowercase first:
// [countedSet addObject:[substring lowercaseString]];
}];
NSLog(#"%#", countedSet);
NSLog(#"%#", [countedSet allObjects]);
NSLog(#"%d", [countedSet countForObject:#"w"]);
The exact answer depends on some questions -
Do you only want to count the characters a-z or do you want punctuation as well?
Do you need to count unicode characters or just 8 bit characters?
Is case important ie. is A different to a?
Assuming you only want to count 8 bit, a-z independent of case, you could use something like -
- (NSArray *)countCharactersInString:(NSString *)inputString
{
NSMutableArray *result=[[NSMutableArray alloc]initWithCapacity:26];
for (int i=0;i<26;i++) {
[result addObject:[NSNumber numberWithInt:0]];
}
for (int i=0;i<[inputString length];i++)
{
unichar c=[inputString characterAtIndex:i];
c=tolower(c);
if (isalpha(c))
{
int index=c-'a';
NSNumber *count=[result objectAtIndex:index];
[result setObject:[NSNumber numberWithInt:[count intValue]+1] atIndexedSubscript:index];
}
}
return (result);
}
An alternative approach is to use an NSCountedSet - it handles all characterspunctuation etc, but will be 'sparse' - there is no entry for a character that is not present in the string. Also, the implementation below is case sensitive - W is different to w.
- (NSCountedSet *)countCharactersInString:(NSString *)inputString
{
NSCountedSet *result=[[NSCountedSet alloc]init];
for (int i=0;i<[inputString length];i++)
{
NSString *c=[inputString substringWithRange:NSMakeRange(i,1)];
[result addObject:c];
}
return result;
}
NSString *str = #"Program to Find the Frequency of Characters in a String";
NSMutableDictionary *frequencies = [[NSMutableDictionary alloc]initWithCapacity:52];
initWithCapacity:52 - capacity can be more depends on character set (for now : a-z, A-Z)
for (short i=0; i< [str length]; i++){
short index = [str characterAtIndex:i];
NSString *key = [NSString stringWithFormat:#"%d",index];
NSNumber *value = #1;
short frequencyCount=0;
if ([frequencies count] > 0 && [frequencies valueForKey:key]){
frequencyCount = [[frequencies valueForKey:key] shortValue];
frequencyCount++;
value = [NSNumber numberWithShort:frequencyCount];
[frequencies setValue:value forKey:key];
}
else{
[frequencies setValue:value forKey:key];
}
}
To display occurrence of each character in string
[frequencies enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
NSString *ky = (NSString*)key;
NSNumber *value = (NSNumber*)obj;
NSLog(#"%c\t%d", ([ky intValue]), [value shortValue]);
}];

Regex in objective C

I want to extract only the names from the following string
bob!33#localhost #clement!17#localhost jack!03#localhost
and create an array [#"bob", #"clement", #"jack"].
I have tried NSString's componentsseparatedbystring: but it didn't work as expected. So I am planning to go for regEx.
How can I extract strings between ranges and add it to an array
using regEx in objective C?
The initial string might contain more than 500 names, would it be a
performance issue if I manipulate the string using regEx?
You can do it without regex as below (Assuming ! sign have uniform pattern in your all words),
NSString *names = #"bob!33#localhost #clement!17#localhost jack!03#localhost";
NSArray *namesarray = [names componentsSeparatedByString:#" "];
NSMutableArray *desiredArray = [[NSMutableArray alloc] initWithCapacity:0];
[namesarray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSRange rangeofsign = [(NSString*)obj rangeOfString:#"!"];
NSString *extractedName = [(NSString*)obj substringToIndex:rangeofsign.location];
[desiredArray addObject:extractedName];
}];
NSLog(#"%#",desiredArray);
output of above NSLog would be
(
bob,
"#clement",
jack
)
If you still want to get rid of # symbol in above string you can always replace special characters in any string, for that check this
If you need further help, you can always leave comment
NSMutableArray* nameArray = [[NSMutableArray alloc] init];
NSArray* youarArray = [yourString componentsSeparatedByString:#" "];
for(NSString * nString in youarArray) {
NSArray* splitObj = [nString componentsSeparatedByString:#"!"];
[nameArray addObject:[splitObj[0]]];
}
NSLog(#"%#", nameArray);
I saw the other solutions and it seemed no one tried to use real regular expressions here, so I created a solution which uses it, maybe you or someone else can use it as a possible idea in the future:
NSString *_names = #"bob!33#localhost #clement!17#localhost jack!03#localhost";
NSError *_error;
NSRegularExpression *_regExp = [NSRegularExpression regularExpressionWithPattern:#" ?#?(.*?)!\\d{2}#localhost" options:NSRegularExpressionCaseInsensitive error:&_error];
NSMutableArray *_namesOnly = [NSMutableArray array];
if (!_error) {
NSLock *_lock = [[NSLock alloc] init];
[_regExp enumerateMatchesInString:_names options:NSMatchingReportProgress range:NSMakeRange(0, _names.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
if (result.numberOfRanges > 1) {
if ([_lock tryLock]) [_namesOnly addObject:[_names substringWithRange:[result rangeAtIndex:1]]], [_lock unlock];
}
}];
} else {
NSLog(#"error : %#", _error);
}
the result can be logged...
NSLog(#"_namesOnly : %#", _namesOnly);
...and that will be:
_namesOnly : (
bob,
clement,
jack
)
Or even something as simple as this will do the trick:
NSString *strNames = #"bob!33#localhost #clement!17#localhost jack!03#localhost";
strNames = [[strNames componentsSeparatedByCharactersInSet:[[NSCharacterSet letterCharacterSet] invertedSet]]
componentsJoinedByString:#""];
NSArray *arrNames = [strNames componentsSeparatedByString:#"localhost"];
NSLog(#"%#", arrNames);
Output:
(
bob,
clement,
jack,
""
)
NOTE: Ignore the last element index while iterating or whatever
Assumption:
"localhost" always comes between names
I know it ain't so optimized but it's one way to do this

Resources