Help with a For loop and NSMutableDictionary - iphone

I am using a for loop to (currently) NSLog the contents of a NSArray. However I would like to set the contents of the array into a NSMutableDictionary, depending on the objectAtIndex it is. Currently there are 843 objects in the array, and therefore I would rather not have to type out the same thing over and over again!
My code currently is this
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
string = [string stringByReplacingOccurrencesOfString:#"\n" withString:#""];
NSArray *chunks = [string componentsSeparatedByString:#","];
for (int i = 0; i < [chunks count]; i ++) {
NSLog(#"%#", [chunks objectAtIndex:i]);
}
I would like to set the contents of the array into the NSMutableDictionary in the following fashion, and once the objectAtIndex is 11, I would like to set the 12th object in the dictionary to be of the key #"type" and soforth:
[dict setObject:[chunks objectAtIndex:0] forKey:#"type"];
[dict setObject:[chunks objectAtIndex:1] forKey:#"name"];
[dict setObject:[chunks objectAtIndex:2] forKey:#"street"];
[dict setObject:[chunks objectAtIndex:3] forKey:#"address1"];
[dict setObject:[chunks objectAtIndex:4] forKey:#"address2"];
[dict setObject:[chunks objectAtIndex:5] forKey:#"town"];
[dict setObject:[chunks objectAtIndex:6] forKey:#"county"];
[dict setObject:[chunks objectAtIndex:7] forKey:#"postcode"];
[dict setObject:[chunks objectAtIndex:8] forKey:#"number"];
[dict setObject:[chunks objectAtIndex:9] forKey:#"coffee club"];
[dict setObject:[chunks objectAtIndex:10] forKey:#"latitude"];
[dict setObject:[chunks objectAtIndex:11] forKey:#"longitude"];

I'm not sure I fully understand the question, but I think that your chunks array contains a long list of data, ordered in the same way (i.e. 0th, 12th, 24th, 36th... elements are all type, and 1st, 13th, 25th, 37th... elements are all name). If this is the case, you could use something like this:
NSArray *keys = [NSArray arrayWithObjects:#"type", #"name", #"street", #"address1", #"address2", #"town", #"county", #"postcode", #"number", #"coffee club", #"latitude", #"longitude", nil];
for (NSUInteger i = 0; i < [chunks count]; i += [keys count])
{
NSArray *subarray = [chunks subarrayWithRange:NSMakeRange(i, [keys count])];
NSDictionary *dict = [[NSDictionary alloc] initWithObjects:subarray forKeys:keys];
// do something with dict
[dict release];
}
Note that you can't have two different values for the same key with NSDictionary. That is, if you set two different values for the type key, only the last value set will be kept.
Edit
If your array is not a multiple of 12 because for example it contains garbage data at the end, you could use a different looping style instead:
// max should be a multiple of 12 (number of elements in keys array)
NSUInteger max = [chunks count] - ([chunks count] % [keys count]);
NSUInteger i = 0;
while (i < max)
{
NSArray *subarray = [chunks subarrayWithRange:NSMakeRange(i, [keys count])];
NSDictionary *dict = [[NSDictionary alloc] initWithObjects:subarray forKeys:keys];
// do something with dict
[dict release];
i += [keys count];
}

Since there's no pattern to your keys, you're better off doing it manually like you're doing it now.

The most straightforward thing to do would be to use the code you posted. But if you really want to use a loop, something like this should do.
NSArray *keys = [NSArray arrayWithObjects:#"type", #"name", #"street", #"address1", #"address2", #"town", #"county", #"postcode", #"number", #"coffee club", #"latitude", #"longitude", nil];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
string = [string stringByReplacingOccurrencesOfString:#"\n" withString:#""];
NSArray *chunks = [string componentsSeparatedByString:#","];
for (int i = 0; i < [chunks count] && i < [keys count]; i ++) {
[dict setObject:[chunks objectAtIndex:i] forKey:[keys objectAtIndex:i]];
}

NSArray* keys = [NSArray arrayWithObjects:#"type",#"name",#"street",#"address1",#"address2",#"town",#"county",#"postcode",#"number",#"coffee club",#"latitude",#"longitude",nil];
for (int i = 0; i < [chunks count]; i ++){
[dict setObject:[chucks objectAtIndex:i] forKey:[keys objectAtIndex:i]];
}

Related

Convert NSString to NSDictionary separated by specific character

I need to convert this "5?8?519223cef9cee4df999436c5e8f3e96a?EVAL_TIME?60?2013-03-21" string into dictionary. Separated by "?"
Dictionary would be some thing like
{
sometext1 = "5",
sometext2 = "8",
sometext3 = "519223cef9cee4df999436c5e8f3e96a",
sometext4 = "EVAL_TIME",
sometext5 = "60",
sometext6 = "2013-03-21"
}
Thank you .
Break the string to smaller strings and loop for them.
This is the way
NSArray *objects = [inputString componentsSeparatedByString:#"?"];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
int i = 1;
for (NSString *str in objects)
{
[dict setObject:str forKey:[NSString stringWithFormat:#"sometext%d", i++]];
}
Try
NSString *string = #"5?8?3519223cef9cee4df999436c5e8f3e96a?EVAL_TIME?60?2013-03-21";
NSArray *stringComponents = [string componentsSeparatedByString:#"?"];
//This is very risky, your code is at the mercy of the input string
NSArray *keys = #[#"cid",#"avid",#"sid",#"TLicense",#"LLicense",#"date"];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
for (int idx = 0; idx<[stringComponents count]; idx++) {
NSString *value = stringComponents[idx];
NSString *key = keys[idx];
[dictionary setObject:value forKey:key];
}
EDIT: More optimized
NSString *string = #"5?8?3519223cef9cee4df999436c5e8f3e96a?EVAL_TIME?60?2013-03-21";
NSArray *stringComponents = [string componentsSeparatedByString:#"?"];
NSArray *keys = #[#"cid",#"avid",#"sid",#"TLicense",#"LLicense",#"date"];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObjects:stringComponents forKeys:keys];
first separate the string into several arrays by '?'.
then add the string in you dictionary.
sth like this:
NSString *str = #"5?8?519223cef9cee4df999436c5e8f3e96a?EVAL_TIME?60?2013-03-21";
NSArray *valueArray = [str componentsSeparatedByString:#"?"];
NSMutableArray *keyArray = [[NSMutableArray alloc] init];
for (int i = 0; i <[valueArray count]; i ++) {
[keyArray addObject:[NSString stringWithFormat:#"sometext%d",i+1]];
}
NSDictionary *dic = [[NSDictionary alloc] initWithObjects:valueArray forKeys:keyArray];
For the future: If you were to store your data in JSON format (closer to what you have anyway), it'll be much easier to deal with and transfer between systems. You can easily read it...using NSJSONSerialization

Auto-incrementing a key in a NSMutableDictionary

I want to auto-incrementing a key and at to a NSMutableDictionary.
I tried to do it but it wasn't work :
NSMutableDictionary *array = [[NSMutableDictionary alloc] init];
int testAutoIndex = 0;
[array setObject:[NSNumber numberWithInt:testAutoIndex++] forKey:#"index"];
[array release];
Thanks :)
Use this:
NSMutableDictionary *array = [[NSMutableDictionary alloc] init];
int testAutoIndex = 0;
[array setObject:[NSNumber numberWithInt:++testAutoIndex] forKey:#"index"];
[array release];
If you want to create a dictionary with say N entries, then it is possible to do using the code
int N = 100; // or what ever number you want
NSArray *arrayOfObjectsYouWantToPumpIntoDictionary = ....;
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithCapacity:100];
for(int i=0;i<N;i++){
NSString *key = [NSString stringWithFormat:#"%d"i];
[mutableDictionary setObject:[arrayOfObjectsYouWantToPumpIntoDictionary objectAtIndex:i] forKey:];
}
// Later some where else if you want to retrieve object with key of x (x can be 1, or 2 or what ever value), you can do
objectToBeRetrieved = [mutableDictionary objectForKey:[NSString stringWithFormat:#"%d",x];

NSMutableDictionary does not sort correctly

Let i have unsorted NSMutableDictionary
{
A = "3";
B = "2";
C = "4";
}
And i need result to be like:
{
B = "2";
A = "3";
C = "4";
}
How can i achieve this result in objective c.
A simple code implementation will be appreciated.
Not possible with an NSMutableDictionary, it is not a sorted structure. You will have to turn it into an NSArray and then sort that. You will then not have a dictionary structure.
You can not sort NSMutableDictionary by value as #joe and #mavrick3 answer. However if you change there keys and values to NSArray you can do it..
Here is simple implementation..
NSMutableDictionary *results; //dictionary to be sorted
NSMutableDictionary *results; //dict to be sorted
NSArray *sortedKeys = [results keysSortedByValueUsingComparator: ^(id obj1, id obj2) {
if ([obj1 integerValue] > [obj2 integerValue])
return (NSComparisonResult)NSOrderedDescending;
if ([obj1 integerValue] < [obj2 integerValue])
return (NSComparisonResult)NSOrderedAscending;
return (NSComparisonResult)NSOrderedSame;
}];
NSArray *sortedValues = [[results allValues] sortedArrayUsingSelector:#selector(compare:)];
//Descending order
for (int s = ([sortedValues count]-1); s >= 0; s--) {
NSLog(#" %# = %#",[sortedKeys objectAtIndex:s],[sortedValues objectAtIndex:s]);
}
//Ascending order
for (int s = 0; s < [sortedValues count]; s++) {
NSLog(#" %# = %#",[sortedKeys objectAtIndex:s],[sortedValues objectAtIndex:s]);
}
You can try this to sort your Dictionary.
NSMutableDictionary *tmpDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:#"6",#"A",#"3",#"B",#"5",#"C",#"2",#"D",#"21",#"F",#"20",#"G",nil];
NSArray *sortedArray = [tmpDict keysSortedByValueUsingComparator:^NSComparisonResult(id obj1,id obj2){
return [obj1 compare:obj2 options:NSNumericSearch];
}];
NSLog(#"Sorted = %#",sortedArray);
NSDictionaryas well as NSMutableDictionary cannot be sorted by value. You can only use a NSArray to sort them. But you have to this with your own code and you won't get the same output as you want.
This is the simplest way to do this
NSArray *arr = [NSArray arrayWithObjects:#"2", #"4", #"1", nil];
NSArray *sorted = [arr sortedArrayUsingSelector:#selector(compare:)];
NSLog(#"Pre sort : %#", arr);
NSLog(#"After sort : %#", sorted);
If you have f.ex. array of dictionary (or model objects), you could do this :
NSDictionary *dict1 = [NSDictionary dictionaryWithObject:#"Mannie" forKey:#"name"];
NSDictionary *dict2 = [NSDictionary dictionaryWithObject:#"Zannie" forKey:#"name"];
NSDictionary *dict3 = [NSDictionary dictionaryWithObject:#"Cannie" forKey:#"name"];
NSArray *peopleIKnow = [NSArray arrayWithObjects:dict1, dict2, dict3, nil];
NSSortDescriptor *sorty = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
NSArray *results = [peopleIKnow sortedArrayUsingDescriptors:[NSArray arrayWithObject:sorty]];
NSLog(#"Before : %#", peopleIKnow);
NSLog(#"After : %#", results);

Objects Sorting With date ,Time Problem in Array(Iphone Development)

I have Problem related to array Sorting.
I have an NSMutable array say's A.Which has an class object b on its each index.
class b contain's multiple field Like int,string and nsdate.
I want to sort the A array on the basis of class b time(NSdate) ascendingly.
I follow the date sorting question on stackoverflow but that's only for date array.
Sort NSArray of date strings or objects
Kindly guide me.
Thank's in advance
Here you go just modify some part of code for your requirement
- (NSArray *)sortedWeightEntriesByWeightDate:(NSArray *)unsortedArray {
NSMutableArray *tempArray = [NSMutableArray array];
NSMutableArray *sortedArray = [NSMutableArray arrayWithCapacity:0];
#try {
for(int i = 0; i < [unsortedArray count];i++) {
NSDateFormatter *df = [[NSDateFormatter alloc]init];
MyDataModal *entry = [unsortedArray objectAtIndex:i];
[df setDateFormat:#"yyyy-MM-dd"];
NSDate *date = [df dateFromString:entry.weightDate];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
if(date) {
[dict setObject:entry forKey:#"entity"];
[dict setObject:date forKey:#"date"];
[tempArray addObject:dict];
}
[df release];
}
NSInteger counter = [tempArray count];
NSDate *compareDate;
NSInteger index;
for(int i = 0 ; i < counter; i++) {
index = i;
compareDate = [[tempArray objectAtIndex:i] valueForKey:#"date"];
NSDate *compareDateSecond;
for(int j = i+1 ; j < counter; j++) {
compareDateSecond=[[tempArray objectAtIndex:j] valueForKey:#"date"];
NSComparisonResult result = [compareDate compare:compareDateSecond];
if(result == NSOrderedDescending) {
compareDate = compareDateSecond;
index=j;
}
}
if(i!=index)
[tempArray exchangeObjectAtIndex:i withObjectAtIndex:index];
}
NSInteger counterIndex = [tempArray count];
for(int i = 0; i < counterIndex ; i++) {
[sortedArray addObject:[[tempArray objectAtIndex:i] valueForKey:#"entity"]];
}
}
#catch (NSException * e) {
NSLog(#"An exception occured while sorting weight entries by date");
}
#finally {
return [NSArray arrayWithArray:sortedArray];
}
}
How about:
NSArray *myArray = [NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:[NSDate distantFuture], #"theDate", nil],
[NSDictionary dictionaryWithObjectsAndKeys:[NSDate distantPast], #"theDate", nil],
nil];
NSLog(#"Before sorting: %#", myArray);
NSSortDescriptor *dateSortDescriptor = [NSSortDescriptor sortDescriptorWithKey: #"theDate" ascending: YES];
NSArray *sortedArray = [myArray sortedArrayUsingDescriptors:[NSArray arrayWithObject: dateSortDescriptor]];
NSLog(#"After Sorting: %#", sortedArray);
This presumes that the date you want to sort for has a key (it is a property, essentially.)

Crazy array sorting in tableView! sortedArrayUsingSelector help?

My tableView app loads the data into the table view.
Everything works perfectly, but the array sorting is kind of messed, like you can see in the picture below. I thought about using the sortedArrayUsingSelector, to straighten things up, but I'm not sure which "sorting method" I should use.
How can I sort this so the cells are sorted according the numbers? Like the order would be 1. 2. 3. 4. 5. etc NOT 1. 10. 11. 12. 13. 14. 2. 3. ?
Thanks a lot in advance!!
And a two-liner:
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:nil ascending:YES comparator:^(id obj1, id obj2) { return [obj1 compare:obj2 options:NSNumericSearch]; }];
rowTitleArray = [rowTitleArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]];
Sorry for this convoluted approach, but this does work...
NSArray *rowTitleArray = [[NSArray alloc] initWithObjects:
#"10. Tenth",
#"15. Fifteenth",
#"13. Thirteenth",
#"1. First",
#"2. Second",
#"22. TwentySecond", nil];
NSMutableArray *dictionaryArray = [NSMutableArray array];
for (NSString *original in rowTitleArray) {
NSString *numberString = [[original componentsSeparatedByString:#"."] objectAtIndex:0];
NSNumber *number = [NSNumber numberWithInt:[numberString intValue]];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
number, #"number", original, #"rowTitle", nil];
[dictionaryArray addObject:dict];
}
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:#"number" ascending:YES];
NSArray *sortedDictionaryArray = [dictionaryArray sortedArrayUsingDescriptors:
[NSArray arrayWithObject:descriptor]];
NSMutableArray *sortedRowTitles = [NSMutableArray array];
for (NSDictionary *dict in sortedDictionaryArray) {
[sortedRowTitles addObject:[dict objectForKey:#"rowTitle"]];
}
rowTitleArray = [NSArray arrayWithArray:sortedRowTitles];
NSLog(#"%#", rowTitleArray);
Output:
"1. First",
"2. Second",
"10. Tenth",
"13. Thirteenth",
"15. Fifteenth",
"22. TwentySecond"
I will try to think of a more elegant solution.
Here is a more elegant solution:
NSInteger intSort(id num1, id num2, void *context) {
NSString *n1 = (NSString *) num1;
NSString *n2 = (NSString *) num2;
n1 = [[n1 componentsSeparatedByString:#"."] objectAtIndex:0];
n2 = [[n2 componentsSeparatedByString:#"."] objectAtIndex:0];
if ([n1 intValue] < [n2 intValue]) {
return NSOrderedAscending;
}
else if ([n1 intValue] > [n2 intValue]) {
return NSOrderedDescending;
}
return NSOrderedSame;
}
rowTitleArray = [rowTitleArray sortedArrayUsingFunction:intSort context:NULL];