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

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

Related

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)]];
}

Create array of floats from csv Objective C

I have once again a beginner problem. I have a CSV file that looks something like this:
3.4,2.4,6.30,2.2,53.42,54,1,5
Now, I have a code that can parse this into an array
NSError *error;
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"csv_file" ofType:#"csv" inDirectory:nil];
NSString *string = [NSString stringWithContentsOfFile:filepath encoding:NSUTF8StringEncoding error:&error];
NSArray *array = [array componentsSeparatedByString:#","];
The issue I have is that I can't do math with these numbers (because they are char - or maybe string, not sure -).
My question is, Is there a way like I did but to create the array with floats, or is there a way to make the strings (or chars) in array into floats.
Thank you, and of course if my question isn't clear just let me know.
Let the elements in the array remain instances of NSString (this is what they are). Just when you access an element from the array make it a float like this:
float f = [array[index] floatValue];
You can't have NSArray of floats in Objective-C because NSArray may contain objects only.
You may be looking for the floatValue property
float sum = 0;
for (NSString *numberString in array) {
sum += [numberString floatValue];
}
If you want to put them in a C array:
float floatArray[array.count];
for(i = 0; i < sizeof(floatArray); i++) {
NSString *numberString = array[i];
floatArray[i] = [numberString floatValue];
}
Note that this way of creating a c array will add it to the stack; you'll need to use malloc if you want to add it to the heap.

Neater way to write all these parameters

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]]];
}

obj-c fetching strings from array

i'm new to obj-c (this is my first day class eheh) and i'm trying to change a label with a random string from a multidimensional array. plus, every time the button is hitten you switch the array. i know it's a bit odd eheh… this is the IBAction:
UIButton *button = (UIButton *)sender;
NSMutableArray *firstArray = [NSMutableArray array];
[firstArray addObject:#"foo"];
NSMutableArray *secondArray = [NSMutableArray array];
[secondArray addObject:#"bar"];
NSMutableArray *frasi = [NSMutableArray array];
[frasi addObject:firstArray];
[frasi addObject:secondArray];
NSMutableArray *array = [NSMutableArray arrayWithObjects:[frasi objectAtIndex:[button isSelected]], nil];
NSString *q = [array objectAtIndex: (arc4random()% [array count] )];
NSString *lab = [NSString stringWithFormat:#"%#", q];
self.label.text = lab;
all works, but the new label is
( "foo" )
instead of just foo (without quotes)... probably i mess in the last block of code...
ty
So, you create 2 mutable arrays, then add them to a new mutable array frasi. Then you get one of those two arrays and use it as the single element (because you use arrayWithObjects: instead of arrayWithArray:) of a new array array.
So array is an array that contains a single array element (instead of an array of strings as you may believe).
When you get an object from array, it's always the same single object that was used to initialize it: either firstArray or secondArray.
So you get an array of strings where you expect a string. When using stringWithFormat:, the specifier %# is replaced with the string description of that object.
A string returns itself as its own description. But the description of an array is the list of all its elements separated with commas and surrounded by parenthesis, which is why you get ( "foo" ).
So instead or creating unneeded arrays, you may just replace all the 8th last lines with this:
NSArray *array = [button isSelected] ? secondArray : firstArray;
self.label.text = [array objectAtIndex:arc4_uniform([array count])];
Actually u have array within array
Replace this line with yours:
NSString *q = [[array objectAtIndex: (arc4random()% [array count] )] objectAtIndex:0];

Sorting NSDictionary

I was wondering if someone can show me how to sort an NSDictionary; I want to read it starting from the last entry, since the key is Date + Time and I want to be able to append it to an NSMutableString. I was able to read it using an enumerator but I don't get the results I want.
Thanks
For your requirements the easiest way is to create a new array from the keys, sort that, then use the array to reference items from the original dictionary.
(Note myComparison is your own method that will compare two keys).
NSMutableArray* tempArray = [NSMutableArray arrayWithArray:[myDict allKeys]];
[tempArray sortedArrayUsingSelector:#selector(myComparison:)];
for (Foo* f in tempArray)
{
Value* val = [myDict objectForKey:f];
}
I've aggregated some of the other suggestions on StackOverflow on sorting an NSDictionary into something very compact that will sort alphabetically. I have a Plist file in 'path' that I load in to memory and want to dump.
NSDictionary *glossary = [NSDictionary dictionaryWithContentsOfFile: path];
NSArray *array1 = [[glossary allKeys] sortedArrayUsingDescriptors:#[ [NSSortDescriptor sortDescriptorWithKey:#"" ascending:YES selector:#selector(localizedStandardCompare:)] ]];
for ( int i=0; i<array1.count; i++)
{
NSString* key = [array1 objectAtIndex:i];
NSString* value = [glossary objectForKey:key];
NSLog(#"Key=%#, Value=%#", key, value );
}