I have an array that contains different date values. And I have used the following code to sort the date array, its done.
combinedArr = [[NSMutableArray alloc]init];
NSInteger counts = [pbTitle count];
for (int i = 0; i < counts; i++) {
CustomObject *customobject2 = [CustomObject customObjectWithName:
[pbTitle objectAtIndex:i] andDate:[pbstartDate objectAtIndex:i]];
[combinedArr addObject:customobject2];
}
[combinedArr sortUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
return [[(CustomObject*)obj1 date]compare: [(CustomObject*)obj2 date]];
}];
NSLog(#"Results: %#", combinedArr);
Now the result is in the combinedArr, I need to check the each value with current system time and need to load into two different arrays, and load these two arrays into two sections of a tableView. How can I implement that? Please help me to find a solution.
I think that the simplest and the fastest (shorter running time) solution is to create 2 separate arrays from the beginning and sort each one separately.
Like this:
NSDate *currentDate = [NSDate date];
NSMutableArray *pastArray = [[NSMutableArray alloc] init];
NSMutableArray *futureArray = [[NSMutableArray alloc] init];
NSInteger counts = [pbTitle count];
// Fill the arrays
for (int i = 0; i < counts; i++) {
NSDate *customOnjectDate = [pbstartDate objectAtIndex:i];
CustomObject *customobject2 = [CustomObject customObjectWithName:[pbTitle objectAtIndex:i] andDate:customOnjectDate];
NSMutableArray *array = ([customOnjectDate compare:currentDate] == NSOrderedAscending ? pastArray : futureArray);
[array addObject:customobject2];
}
// Sort the arrays
[pastArray sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [[obj1 date] compare:[obj2 date]];
}];
[futureArray sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [[obj1 date] compare:[obj2 date]];
}];
// Use the arrays
NSLog(#"pastArray: %#", pastArray);
NSLog(#"futureArray: %#", futureArray);
// Don't forget to release the arrays after you use them
[pastArray release];
[futureArray release];
Related
I have an app which is retrieving its information from a plist.
The plist is an array of Dictionaries with the keys (author, cat, content).
Now I would like to show the categories in a table.
So I need all unique category entries in a sorted way.
I have successfully implemented following way but I am interested if this is the "right" solution.
Go through plist array and make new NSMutableArray with all category
entries of the dictionary
put this NSMutableArray into a NSSet to get unique Elements
put this NSSet into an NSArray to have the possibility to sort it.
return a NSMutableArray initiated with the sorted NSArray
I feel not , that this is the right way of doing so.
Any suggestions to do it better ?
Thanks a lot!
//InhaltefromWEb is a NSMutableArray
-(NSArray*) getCategories {
NSMutableArray* categorieTemp = [[NSMutableArray alloc] init];
unsigned count = [InhalteFromWeb count];
while (count--) {
NSString *tempString;
tempString=[[InhalteFromWeb objectAtIndex:count] objectForKey:CATEGORY];
NSLog(#"tempString %#", tempString );
[categorieTemp addObject:tempString];
}
NSSet *uniqueElements = [NSSet setWithArray:categorieTemp];
NSLog(#"categories from engine %#", categorieTemp);
NSArray* tempAr = [[[NSArray alloc] initWithArray:[uniqueElements allObjects]]sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
return [NSMutableArray arrayWithArray:tempAr];
}
Check for existing String with [categorieTemp containsObject:tempString] and sort it with [categorieTemp sortUsingComparator:...]
Example:
[categorieTemp sortUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
return [(NSString *)obj1 caseInsensitiveCompare:(NSString *)obj2];
}];
I do this to sort my array for a date:
[array sortedArrayUsingComparator: ^(id obj1, id obj2) {
NSDate *date1 = [obj1 objectForKey:#"datum"] == nil ? nilDate : [obj1 objectForKey:#"datum"];
NSDate *date2 = [obj2 objectForKey:#"datum"] == nil ? nilDate : [obj2 objectForKey:#"datum"];
return (NSComparisonResult)[date2 compare: date1];
}];
i have the following code
inAppKeys = [[MKStoreManager sharedManager] purchasableObjectsDescription ];
NSMutableArray * unremovableArray = [[NSMutableArray alloc] init];
for(int i = 0; i<[inAppKeys count]; i++){
for (int j=0; j< [categories count]; j++) {
NSString * inAppKey = [[categories objectAtIndex:j] valueForKey:#"inAppKey"];
if([inAppKey isEqualToString: [inAppKeys objectAtIndex:i]]){
[unremovableArray addObject:[categories objectAtIndex:j]];
}
}
}
categories = [[NSMutableArray alloc] init];
[categories addObjectsFromArray:unremovableArray];
where categories is nsmutablearray .. the thing is addObjectsFromArray leave the categories empty .. what do i do wrong?
Looks to me like you're referring to [categories count] and [categories objectAtIndex:j] before you even alloc/init categories.
Having re-read your title ("reinitializing") which suggests you've previously inited categories, I'm now assuming that you have a master set of categories that you're trying to reduce to the ones actually purchased. If so, I wouldn't re-use the variable "categories" as that's confusing. (I assume categories was auto-released, or else you've got a leak). How 'bout using unremovableArray instead of leaking it?
I'd also use fast enumerators for clarity and speed...
NSLog(#"categories: %#", categories);
inAppKeys = [[MKStoreManager sharedManager] purchasableObjectsDescription ];
NSLog(#"inAppKeys:%#", inAppKeys);
NSMutableArray * unremovableCategories = [[NSMutableArray alloc] init];
for(NSString* thisAppKey in inAppKeys) {
for (NSDictionary* thisCategory in categories) {
if ([[thisCategory valueForKey:#"inAppKey"] isEqualToString: thisAppKey]){
[unremovableCategories addObject:thisCategory];
break; //having added this category; no reason to continue looking at it
}
}
}
//now use unremovableCategories...
i need some help here, i need to know how to create an array of string retrieved from an array. i'm using powerplot for graph and it only accept float or string array.
i need to create something something like this dynamically.
NSString * sourceData[7] = {#"2", #"1", #"4", #"8", #"14", #"15", #"10"};
Below are my code to find out the numbers in strings.
NSInteger drunked = [appDelegate.drinksOnDayArray count];
NSMutableArray * dayArray = [[NSMutableArray alloc] init];
NSMutableArray * sdArray = [[NSMutableArray alloc] init];
//float *sdArray[7];
for (int i=0; i<drunked; i++) {
DayOfDrinks *drinksOnDay = [appDelegate.drinksOnDayArray objectAtIndex:i];
NSString * dayString= [NSDate stringForDisplayFromDateForChart:drinksOnDay.dateConsumed];
[dayArray addObject:dayString];
NSLog(#"%#",[dayArray objectAtIndex:i]);
drinksOnDay.isDetailViewHydrated = NO;
[drinksOnDay hydrateDetailViewData];
NSString * sdString= [NSString stringWithFormat:#"%#", drinksOnDay.standardDrinks];
[sdArray addObject:sdString];
NSString *tempstring;
NSLog(#"%#",[sdArray objectAtIndex:i]);
}
thanks for the help :)
Array's in Objectice-C aren't that hard to work with:
NSMutableArray *myArray = [NSMutableArray array];
[myArray addObject:#"first string"]; // same with float values
[myArray addObject:#"second string"];
[myArray addObject:#"third string"];
int i;
int count;
for (i = 0, count = [myArray count]; i < count; i = i + 1)
{
NSString *element = [myArray objectAtIndex:i];
NSLog(#"The element at index %d in the array is: %#", i, element); // just replace the %# by %d
}
You can either use NSArray or NSMutableArray - depending on your needs, they offer different functionality.
Following tutorial covers exactly what you are looking after:
http://www.cocoalab.com/?q=node/19
You can also add the elements to the array when you init (and optionally add them later only if you are using the Mutable version of a collection class:
NSMutableArray *myArray = [[NSMutableArray alloc] initWithObjects:#"2", #"1", #"4", #"8", #"14", #"15", #"10", nil];
[myArray addObject:#"22"];
[myArray addObject:#"50"];
//do something
[myArray release];
You can use malloc to create a C-style array. something like this should work:
NSString **array = malloc(numElements * sizeof(NSString *))
some code here
free(array)
Be aware that unlike NSMutable array, c arrays won't do a retain, so you have to manage it if needed. And don't forget the free
I need to sort a NSDictionary of dictionaries. It looks like:
{//dictionary
RU = "110.1"; //key and value
SG = "150.2"; //key and value
US = "50.3"; //key and value
}
Result need to be like:
{//dictionary
SG = "150.2"; //key and value
RU = "110.1"; //key and value
US = "50.3"; //key and value
}
I am trying this:
#implementation NSMutableDictionary (sorting)
-(NSMutableDictionary*)sortDictionary
{
NSArray *allKeys = [self allKeys];
NSMutableArray *allValues = [NSMutableArray array];
NSMutableArray *sortValues= [NSMutableArray array];
NSMutableArray *sortKeys= [NSMutableArray array];
for(int i=0;i<[[self allValues] count];i++)
{
[allValues addObject:[NSNumber numberWithFloat:[[[self allValues] objectAtIndex:i] floatValue]]];
}
[sortValues addObjectsFromArray:allValues];
[sortKeys addObjectsFromArray:[self allKeys]];
[sortValues sortUsingDescriptors:[NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:#"floatValue" ascending:NO] autorelease]]];
for(int i=0;i<[sortValues count];i++)
{
[sortKeys replaceObjectAtIndex:i withObject:[allKeys objectAtIndex:[allValues indexOfObject:[sortValues objectAtIndex:i]]]];
[allValues replaceObjectAtIndex:[allValues indexOfObject:[sortValues objectAtIndex:i]] withObject:[NSNull null]];
}
NSLog(#"%#", sortKeys);
NSLog(#"%#", sortValues);
NSLog(#"%#", [NSMutableDictionary dictionaryWithObjects:sortValues forKeys:sortKeys]);
return [NSMutableDictionary dictionaryWithObjects:sortValues forKeys:sortKeys];
}
#end
This is the result of NSLog:
1)
{
SG,
RU,
US
}
2)
{
150.2,
110.1,
50.3
}
3)
{
RU = "110.1";
SG = "150.2";
US = "50.3";
}
Why is this happening? Can you help me with this problem?
NSDictionary are unsorted by nature. The order of the objects as retrieved by allKeys and allValues will always be undetermined. Even if you reverse engineer the order it may still change in the next system update.
There is however more powerful alternatives to allKeys that are used to retrieve the keys in a defined and predictable order:
keysSortedByValueUsingSelector: - Useful for sorting in ascending order according to the compare: method of the value objects.
keysSortedByValueUsingComparator: - New in iOS 4, use a block to do the sort inline.
WOW. Thanx, PeyloW! It's what i needed! I also find this code and it helps me to reorder results:
#implementation NSString (numericComparison)
- (NSComparisonResult) floatCompare:(NSString *) other
{
float myValue = [self floatValue];
float otherValue = [other floatValue];
if (myValue == otherValue) return NSOrderedSame;
return (myValue < otherValue ? NSOrderedAscending : NSOrderedDescending);
}
- (NSComparisonResult) intCompare:(NSString *) other
{
int myValue = [self intValue];
int otherValue = [other intValue];
if (myValue == otherValue) return NSOrderedSame;
return (myValue < otherValue ? NSOrderedAscending : NSOrderedDescending);
}
#end
a NSDictionary is not ordened, so it doens't matter in what order you construct a NSDIctionary.
a NSArray is ordened. If you want to have the NSDictionary ordened in memory, you should somehow make a NSArray of key value pairs. You can also return two NSArrays with corresponding indeces.
If you only want to iterate over the elements way, you can iterate over a sorted array of keys (this is what koregan suggests).
quick question regarding Array's in xcode. I have ht efollowing code, which is supposed to go through an array of strings which it has got through php and JSON, and trun these strings into a custom object with the strings as the ivars for the object then add that object to a new array:
for (int i = 0; i<[list count]; i++) {
Article *article = [[Article alloc] init]; //creates custom object
article.uid = [[list objectAtIndex:i] objectAtIndex:0];
article.title = [[list objectAtIndex:i] objectAtIndex:1]; //adds string as ivars
article.description = [[list objectAtIndex:i] objectAtIndex:2];
articleArray = [[NSMutableArray alloc] init]; //inits the new array
[articleArray addObject:article]; //should add the object but seems to fail
[article release]; //releases the object
NSLog(#"%#", article.description);
}
NSLog(#"%d", [articleArray count]);
NSLog([articleArray description]);
}
The code does return the correct values using NSLog(#"%#", article.description); but not the correct length for the new array and it only adds one value to the array which is the string for article.description which makes no sense to me. The list array contains 2 elements each of which are arrays in themselves containing the strings.
You're recreating the articleArray in every loop. Declarate it outside, and it will work:
NSMutableArray *articleArray = [[NSMutableArray alloc] init]; //inits the new array
for (int i = 0; i<[list count]; i++) {
Article *article = [[Article alloc] init]; //creates custom object
article.uid = [[list objectAtIndex:i] objectAtIndex:0];
article.title = [[list objectAtIndex:i] objectAtIndex:1]; //adds string as ivars
article.description = [[list objectAtIndex:i] objectAtIndex:2];
[articleArray addObject:article]; //should add the object but seems to fail
[article release]; //releases the object
NSLog(#"%#", article.description);
}
NSLog(#"%d", [articleArray count]);
NSLog([articleArray description]);
}
You also may want to use the nicer for(NSArray *listElement in list) syntax instead.