NSString characterSetWithCharactersInString returns empty strings - ios

I'm trying to break a NSString into the comma separated components. Somehow my NSString containing 25000 components always returns 25.500 values, 500 of which are empty NSStrings. Here's what my code looks like:
NSString* fileContents = [NSString stringWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:nil];
/* do stuff */
NSMutableArray* components =
[NSMutableArray arrayWithArray:
[fileContents componentsSeparatedByCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString:#",\n\r "]]];

Consider this example:
[#"\n,\n"componentsSeparatedByCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString:#",\n\r "]];
The result shows how componentsSeparatedByCharactersInSet: behaves. Four components, all empty strings. Do you see why?
I'm not quite sure what you were expecting it to do, but that is what it does do. It just splits at any of the characters you list. If two of them are next to each other, you get an empty string. Plus a string for before the first one and a string for after the last one.
So the reason you are getting 25500 components is that, given the command you gave, that is how many components there are.

Related

Find difference between two comma separated NSMutableString

Suppose I have two NSMutableString like this:-
String 1 ----- {aaa,bss,cdd,dff,eee,fgh}
String 2 ----- {aaa,bss,cdd}
How can we find the the difference between String 1 & String 2 in an NSArray:-
Like this:- { dff,eee,fgh }
As mentioned in duplicate question it is different.
Put both these strings in two different NSMutableSets and then subtract 2nd from 1st.
You will have your result.
NSString* str1 = #"aaa,bss,cdd,dff,eee,fgh";
NSString* str2 = #"aaa,bss,cdd";
NSMutableSet *set1 = [NSMutableSet setWithArray:[str1 componentsSeparatedByString:#","]];
NSMutableSet *set2 = [NSMutableSet setWithArray:[str2 componentsSeparatedByString:#","]];
[set1 minusSet:set2];
NSLog(#"result %#",[set1 allObjects]);
Try with NSMutableArray to remove same objects.
For Eg.
NSString *s1 = #"aaa,bss,cdd,dff,eee,fgh";
NSString *s2 = #"aaa,bss,cdd";
NSArray *arr1 = [s1 componentsSeparatedByString:#","];
NSArray *arr2 = [s2 componentsSeparatedByString:#","];
NSMutableArray *resArray = [NSMutableArray arrayWithArray:arr1];
[resArray removeObjectsInArray:arr2];
NSString *res = [resArray componentsJoinedByString:#","];
NSLog(#"Result :: %#", res);
Hopefully, it'll help you.
Thanks.
First part of the problem is to separate each string into substrings separated by the commas.
To create the substrings you can use
[string substringFromIndex:index] - to get an NSString from that index foward
[string substringToIndex:index] - to get an NSString from the begining to that index
Or you could combine it into
[string substringWithRange:NSMakeRange(fisrtIndex, secondIndex)] - to get a strin from the first index to the second index
Those are the basic operations. But there are a lot more in this case you could use specifically:
[string componentsSeparatedByString:#","] to get an NSArray with all the substrings. That would have the problem of the '{' and '}' appearing in the first and last component. This can be solved in many ways:
by first trimming the string using the substring methods already explained
by using another method altogether
[string componentsSeparatedByCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:#",{"]] The problem with this method is, because your strings start/end with one of the separators you would get the first/last component an empty string. You can just remove it from the array or ignore it or choose the other method, your choice.
Now that you know how to get the substrings all you need to know is how to compare the two. There are literally many ways to do this. I am just going to name a few. Of course each solution has its own advantages and disadvantages and code complexity.
1 - comparing each substring one by one the the other using isEqualToString:
2 - comparing each substring from one of the original strings with the full second original string by using [string2 rangeOfString:substring].location != NSNotFound
3 - if you have iOS 8 or OS X Yosemite you can use [string2 containsString:substring]
4 - You can transform the arrays of substrings into sets and then compare them as Ankit Srivastava suggested
5 - You can use the removeObjectsInArray to get the substrings that are not common between the two and then use that newly created array to removeObjectsInArray to the original and have just the common...
Really the possibilities are almost endless

Unknown quotation marks added to string object in NSMutableArray after for loop

I have an array of NSString objects, the objects have some unneccessary chars (one object looks like this in the console: "\"stringContent\"") that I'm removing with the below code. It works correctly, however when I log arr1 50-60% of the strings got a quotation marks like this "stringContent", the others don't have it. Actually my problem is that I don't have an why it happens, because when I log the strings in the for loop they don't have the quotation marks. Do anybody has an idea what can causes this?
NSMutableArray * arr1 = [[NSMutableArray alloc ]init];
for (NSString *str in self.stringArray) {
NSString *newString = [str substringToIndex:[brand length]-1];
NSString *nwstr = [newString substringFromIndex:1];
[arr1 addObject:nwstr];
NSLog(#"string %#", nwstr);
}
NSLog(#"array %#", arr1);
Other thing that might be helpful, when I call this every object appears in the console, it's like the quotation marks are hidden for the containsString method, because a lot of them don't meet the requirement of the if statement.
for (NSString *str in arr1) {
if (![str containsString:#"\""]) {
NSLog(#"XXX %#", str);
}
}
When you NSLog an NSArray or NSDictionary, the elements are displayed in a log format which MAY (or may not) include gratuitous quotation marks, escaped characters, etc. Specifically, quotation marks are used around strings, EXCEPT when the strings contain no non-alphabetic characters or blanks.
More detail: What actually happens is that NSLog internally invokes [NSString stringWithFormat:] or one of its kin to format the text to be logged. stringWithFormat:, in turn, invokes the description method of each object in the parameter list that corresponds to a %# format directive. It is the description method of NSArray and NSDictionary which adds the extra characters.

Loop through lines in file and fill NSMutable array with NSStrings

I have an array, lines, that consists of the lines in a text file. I want to choose a particular line based on its first string. So I loop through the file like this:
for(NSString *str in lines)
{
myMutableArray = [str componentsSeparatedByCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:#";"]];
//Get myMutableArray[0] and check if it's the correct line
// If not, empty the NSMutableArray and start over
}
I know that the code line inside the loop will return an NSArray, so this won't work. What is the best way to solve this problem?
Hank
myMutableArray = [[str componentsSeparatedByCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:#";"]] mutableCopy];
Suits?

How do I break in the NSArray with NSString substrings enclosed in quotes

I have a NSSring:
NSString *example = #"'example01','example02','example03','example04'";
How can I make from this line NSArray?
NSString *example = [example stringByReplacingOccurrencesOfString:#"'" withString:#""];
NSArray * exampleArr = [example componentsSeparatedByString:#","];
NSArray *commaSeparatedComponents = [example componentsSeparatedByString:#","];
NSCharacterSet *quotesSet = [NSCharacterSet characterSetWithCharactersInString:#"'"];
for (NSString *component in commaSeparatedComponents) {
NSString *correctlyTrimmedComponent = [component stringByTrimmingCharactersInSet:quotesSet]; // only remove 's at the edges
// ... do something with each component; maybe add to a mutable array ...
}
This has the advantage over the other answer to not remove quotes that exist inside the values, but it doesn't do anything to actually solve quotes escaping that might have been necessary inside the data, and so on. It still misbehaves with some strings, but it misbehaves for fewer cases because it is less flippant about which quotes it removes.
If this is anything above and beyond a string in that exact format, you will probably need a parser for this sort of string that can handle the semantics of how the quotes are escaped, gracefully handles garbage, etc.

Fast Enumeration error?

Getting a warning saying that:
Collection expression type 'NSString *' may not respond to 'countByEnumeratingWithState:objects:count'
when trying to run the following code:
NSString *proper = [NSString stringWithContentsOfFile:#"usr/share/dict/propernames" encoding:NSUTF8StringEncoding error:NULL];
for (NSString *i in proper){
NSLog(#"Item>%#", i);
}
When I run the program I don't get any output from the NSLog statement. Anyone run into this?
The compiler warning is trying to tell you that you cannot iterate over an NSString using a for ... in ... loop. It is further trying to say than the reason for this is that an NSString is not a valid "Collection" type. Your valid "Collection" types are things like NSArray, NSSet, and NSDictionary.
So if your file is supposed to contain structured data, you should parse it into something more useful than a flat NSString. Something like this may give a better result:
NSString* temp = [NSString stringWithContentsOfFile:#"usr/share/dict/propernames" encoding:NSUTF8StringEncoding error:NULL];
NSArray* proper = [temp componentsSeparatedByString:#"\n"];
for (NSString* i in proper){
NSLog(#"Item>%#", i);
}
That will print each line in the file. This assumes, of course, that your input file has one entry per line. If it is structured some other way, then you will have to parse it differently.
After you load the file, split it into lines with componentsSeparatedByString: .
NSArray *lines = [proper componentsSeparatedByString:#"\n"]; // Use the correct line ending character here
for (NSString *i in lines) {
NSLog(#"item> %#", i);
}
This is a clear mistake u have here.
NSString* is a string object and is not a collection of characters as the string object known in C++ which is a character array.
for-in Loop need a collection to iterate within. like NSArray or NSSet.

Resources