Neater way to write all these parameters - objective-c

I have a bunch of saved nsuserdefault parameters that need to be written (20 cars to be exact). I am wondering what will be the neatest way to write this. I number it in order because I believe the for loop will be appropriate(not too sure). The code below represents a snippet of what I am trying to do.
NSString *emailBody=[NSString
stringWithFormat:#"%#, %#, %#",[[NSUserDefaults
standardUserDefaults]stringForKey:#"Car1"],[[NSUserDefaults
standardUserDefaults]stringForKey:#"Car2"],[[NSUserDefaults
standardUserDefaults]stringForKey:#"Car3"]];

There's no reason to save 20 separate items. Just put them in an array and store the array with setObject:forKey:. You can then fetch them all back as an array using stringArrayForKey: (or arrayForKey: or even just objectForKey:).
Once you have an array, creating a comma-separated list is very easy:
NSString *emailBody = [array componentsJoinedByString:#", "];
If you must store them as 20 items for compatibility, I would still pull them out of NSUserDefaults and put them in an array before actually using them.

Just use a for loop, something like this.
NSMutableArray *a = [NSMutableArray array];
for (int i=1;i<21;i++)
{
[a addObject:[NSString stringWithFormat:#"Car%d", i]];
}
Then just put the array into a string.

Slightly neater:
NSMutableString *emailBody = [[NSMutableString alloc] init];
for (unsigned i = 1; i <= 20; i++) {
if (i > 1)
[emailBody appendString:#", "];
[emailBody appendString:[[NSUserDefaults standardUserDefaults]
stringForKey:[StringWithFormat:#"Car%d", i]]];
}

Related

Read from CSV file and create arrays in Objective-C Xcode

I am trying to load a .csv file to Xcode using Objective-C and then I want to create two different arrays. The first array should have values from the first 2 columns and the second array the values of the third column.
I know that what I am looking for is fairly similar to this question, but I am completely newbie in Objective-C and I am a bit confused.
Until now I have tried writing the following code:
NSString* fileContents = [NSString stringWithContentsOfURL:#"2014-07-16_15_41_20.csv"];
NSArray* rows = [fileContents componentsSeparatedByString:#"\n"];
for (int i = 0; i < rows.count; i ++){
NSString* row = [rows objectAtIndex:i];
NSArray* columns = [row componentsSeparatedByString:#","];
}
So, is this piece of code correct until now? Also, how can I divide columns into 2 different arrays in the way I described above?
Your code seems correct. But it's better to use Cocoa Fast Enumeration instead of a for loop with integers.
To divide into arrays your code could look like this.
NSMutableArray *colA = [NSMutableArray array];
NSMutableArray *colB = [NSMutableArray array];
NSString* fileContents = [NSString stringWithContentsOfURL:#"2014-07-16_15_41_20.csv"];
NSArray* rows = [fileContents componentsSeparatedByString:#"\n"];
for (NSString *row in rows){
NSArray* columns = [row componentsSeparatedByString:#","];
[colA addObject:columns[0]];
[colB addObject:columns[1]];
}
Read more about NSMutableArray

How to split an NSString into multiple NSStrings [duplicate]

This question already has answers here:
Is there a simple way to split a NSString into an array of characters?
(4 answers)
Closed 8 years ago.
I'm trying to split an NSString into multiple NSString's. One new string for every character in the NSString. Is there a simpler way to do this than just doing it manually? A method or API that can do this automatically?
For example, turn this string:
_line1 = [NSString stringWithFormat:#"start"];
into:
_string1 = [NSString stringWithFormat:#"s"];
_string2 = [NSString stringWithFormat:#"t"];
_string3 = [NSString stringWithFormat:#"a"];
_string4 = [NSString stringWithFormat:#"r"];
_string5 = [NSString stringWithFormat:#"t"];
The documentation out there is really good. There are lots of ways you could do this.
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html
One way is to make an array of NSStrings that contain each character.
NSString * line1 = #"start";
NSMutableArray * characters = [NSMutableArray array];
for(int i = 0; i < line1.length; i++) {
NSString * character = [line1.substringWithRange:NSMakeRange(i, 1)];
[characters addObject:character];
}
// Then loop over characters array ...
First off, why are you using _line1? You should never access properties directly via their pointer. Please use self.line1 instead. I will assume you have #property NSString *line1; in your class definition. If not, you'll need to adjust the code I'm posting as necessary.
Second, no there's no way built in. But it's pretty simple to do manually:
NSMutableArray *chars = [NSMutableArray array];
NSUinteger i = 0;
for (i = 0; i < self.line1.length; i++) {
[chars addObject:[self.line1 substringWithRange:NSMakeRange(i, 1)]];
}

Modify Object while Iterating over a NSMutableArray

I was trying to modify an object from an array while iterating over it and couldn't find a nice way of doing it... This is what I've done, is there a simpler way of doing this? I've been googling for while but I couldn't find anything...
NSMutableArray *tempArray = [[NSMutableArray alloc]init];
NSArray *days = [restaurant.hours componentsSeparatedByString:#","];
for (NSString *day in days) {
NSString *dayWithOutSpace = [day stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[tempArray addObject:dayWithOutSpace];
}
days = [NSArray arrayWithArray:tempArray];
Thanks!
As suggested by others there might be better ways to accomplish the exact task in the question, but as a general pattern there is nothing wrong with your approach - build a new array.
However if you need to modify a mutable array, say because multiple objects reference it, there is nothing wrong with that either - that is why it is mutable after all! You just need to use standard iteration rather than enumeration - the latter is just the wrong tool for the job. E.g.:
NSMutableArray *anArray = ...
NSUInteger itemCount = [anArray count];
for(NSUInteger ix = 0; ix < itemCount; ix++)
{
// read from anArray[ix] and store into anArray[ix] as required
}
The way you do it is OK, since you are not modifying the array you are looping through.
Here is another way, a little less intuitive and probably not faster:
NSArray* days = [[[restaurant.hours componentsSeparatedByString:#" "] componentsJoinedByString:#""] componentsSeparatedByString:#","];
Considering your hours string is like: 2, 5, 6, 7 etc. you can use the string as #", " directly.
NSArray *days = [restaurant.hours componentsSeparatedByString:#", "];
Maybe it is better to eliminate all white spaces before separation.
NSString *daysWithOutSpaces = [restaurant.hours stringByReplacingOccurrencesOfString:#"[\\s\\n]" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, restaurant.hours.length)];
NSArray *days = [daysWithOutSpaces componentsSeparatedByString:#","];

Searching NSArray using suffixes

I have a word list stored in an NSArray, I want to find all the words in it with the ending 'ing'.
Could someone please provide me with some sample/pseudo code.
Use NSPredicate to filter NSArrays.
NSArray *array = #[#"test", #"testing", #"check", #"checking"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF ENDSWITH 'ing'"];
NSArray *filteredArray = [array filteredArrayUsingPredicate:predicate];
Let's say you have an array defined:
NSArray *wordList = // you have the contents defined properly
Then you can enumerate the array using a block
// This array will hold the results.
NSMutableArray *resultArray = [NSMutableArray new];
// Enumerate the wordlist with a block
[wordlist enumerateObjectsUsingBlock:(id obj, NSUInteger idx, BOOL *stop) {
if ([obj hasSuffix:#"ing"]) {
// Add the word to the result list
[result addObject:obj];
}
}];
// resultArray now has the words ending in "ing"
(I am using ARC in this code block)
I am giving an example using blocks because its gives you more options should you need them, and it's a more modern approach to enumerating collections. You could also do this with a concurrent enumeration and get some performance benefits as well.
Just loop through it and check the suffixes like that:
for (NSString *myString in myArray) {
if ([myString hasSuffix:#"ing"]){
// do something with myString which ends with "ing"
}
}
NSMutableArray *results = [[NSMutableArray alloc] init];
// assuming your array of words is called array:
for (int i = 0; i < [array count]; i++)
{
NSString *word = [array objectAtIndex: i];
if ([word hasSuffix: #"ing"])
[results addObject: word];
}
// do some processing
[results release]; // if you're not using ARC yet.
Typed from scratch, should work :)

string tokenizer in ios

I like to tokenize a string to characters and store the tokens in a string array. I am trying to use following code which is not working as I am using C notation to access the array. What needs to be changed in place of travel path[i]?
NSArray *tokanizedTravelPath= [[NSArray alloc]init];
for (int i=0; [travelPath length]; i++) {
tokanizedTravelPath[i]= [travelPath characterAtIndex:i];
You can't store unichars in an NSArray*. What exactly are you trying to accomplish? An NSString* is already a great representation for a collection of unichars, and you already have one of those.
You need a NSMutableArray to set every element of the array (otherwise you can't change its objects).Also, you can only insert objects in the array, so you can:
- Insert a NSString containing the character;
- Use a C-style array instead.
This is how to do with the NSMutableArray:
NSMutableArray *tokanizedTravelPath= [[NSMutableArray alloc]init];
for (int i=0; i<[travelPath length]; i++)
{
[tokanizedTravelPath insertObject: [NSString stringWithFormat: #"%c", [travelPath characterAtIndex:i]] atIndex: i];
}
I count 3 errors in your code, I explain them at the end of my answer.
First I want to show you a better approach to split a sting into it characters.
While I agree with Kevin that an NSString is a great representation of unicode characters already, you can use this block-based code to split it into substrings and save it to an array.
Form the docs:
enumerateSubstringsInRange:options:usingBlock:
Enumerates the
substrings of the specified type in the specified range of the string.
NSString *hwlloWord = #"Hello World";
NSMutableArray *charArray = [NSMutableArray array];
[hwlloWord enumerateSubstringsInRange:NSMakeRange(0, [hwlloWord length])
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString *substring,
NSRange substringRange,
NSRange enclosingRange,
BOOL *stop)
{
[charArray addObject:substring];
}];
NSLog(#"%#", charArray);
Output:
(
H,
e,
l,
l,
o,
" ",
W,
o,
r,
l,
d
)
But actually your problems are of another nature:
An NSArray is immutable. Once instantiated, it cannot be altered. For mutable array, you use the NSArray subclass NSMutableArray.
Also, characterAtIndex does not return an object, but a primitive type — but those can't be saved to an NSArray. You have to wrap it into an NSString or some other representation.
You could use substringWithRange instead.
NSMutableArray *tokanizedTravelPath= [NSMutableArray array];
for (int i=0; i < [hwlloWord length]; ++i) {
NSLog(#"%#",[hwlloWord substringWithRange:NSMakeRange(i, 1)]);
[tokanizedTravelPath addObject:[hwlloWord substringWithRange:NSMakeRange(i, 1)]];
}
Also your for-loop is wrong, the for-loop condition is not correct. it must be for (int i=0; i < [travelPath length]; i++)