Objective-C NSMutableArray: Organize array of photos by date key - objective-c

I have an array of dictionaries..looks like this.
(
{name = somename;
date = NSDate;
other_params = some other params;
},
...
)
How can I then sort the array items by NSDate (oldest to newest or vice versa). Do I just do a basic select-sort algorithm or is there a shorter way?

You can sort the array using descriptors or using comparators, whatever you feel more comfortable with. Here is an example of using comparators:
NSArray *sortedArray = [myArray sortedArrayUsingComparator: ^(id obj1, id obj2) {
return [[obj1 date] compare:[obj2 date]];
}];

Here's the sort descriptors option:
// Adjust the 'ascending' option to invert the sort order.
NSSortDescriptor *dateSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"date" ascending:YES];
// The sort descriptors have to go into an array.
NSArray *sortDescriptors = [NSArray arrayWithObject:dateSortDescriptor];
NSArray *sortedArray = [myArray sortedArrayUsingDescriptors:sortDescriptors];
You can also sort in place if you're using an NSMutableArray and don't need to keep its original order.

Related

Inserting NSDictionary into sorted NSMutableArray

I want to insert an NSDictionary object into an array and have the array sorted by objectForKey.
I managed to do this by inserting, re-sorting and reloading the array, which works fine, but I figured there would be a better method, which there is, I just don't know how to use it.
Current code:
-(NSMutableArray*)sortArray:(NSMutableArray*)theArray {
return [[theArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:#"n"
ascending:YES]]] mutableCopy];
}
returns the re-sorted array. Fine. Works perfectly, but... is it the most efficient?
From another question I gather that this is the method to use to find the index to insert into:
NSUInteger newIndex = [array indexOfObject:newObject
inSortedRange:(NSRange){0, [array count]}
options:NSBinarySearchingInsertionIndex
usingComparator:comparator];
[array insertObject:newObject atIndex:newIndex];
The problem is I have no idea how to use the comparator method, and if that's even possible when I want to sort by objectForKey for each index.
Can anyone exemplify the above method when the key of the object (newObject in above example) to sort by is, let's say:
[newObject objectForKey:#"sortByThis"];
Use NSSortDescriptor
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"sortByThisKey" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [myArray sortedArrayUsingDescriptors:sortDescriptors];
here is the simple example for comparator
- (NSComparisonResult)compareResulst:(CustomObject *)otherObject {
if(self.name isEqualToString:key)
{
return NSOrderedAscending;
}
else
{
return NSOrderedDescending
}
}
NSArray *sArray;
sArray = [unsArray sortedArrayUsingSelector:#selector(compareResulst:)];
this will sort the array. it will iterate through object and based on your if else it will move object up and down ...
Here's an example of sorting
//For make a we're adding 5 random integers into array inform of NSDictionary
//here, we're taking "someKey" to store the integer (converted to string object) into dictionary
NSMutableArray *array = [NSMutableArray array];
for(int i = 1; i<=5; i++) {
[array addObject:[NSDictionary dictionaryWithObject:[#(arc4random()%10) stringValue] forKey:#"someKey"]];
}
//create a sort descriptor to sort the array
//give the key in dictionary for which you want to perform sort
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:#"someKey" ascending:YES];
//we're doing self sort for mutable array, & that's it, you'll have a sorted array.
[array sortUsingDescriptors:#[sort]];
N.B.
1.Instead of "someKey" from above example you can set any key for which you want to perform sort.
2.There's some other methods for sorting, you can use the one base on your requirement.
3.see #[sort] in code. Its full version is, [NSArray arrayWithObject:sort];

Ordering an NSArray with NSDictionaries with objects

I have an array of dictionaries that contains objects like in the image below:
The problem I have is that I need to order the array by dates, for example in the first object I have a dueDate that is greater than the dueDate of the second object, then I have to swap them, so in other word I need to order the dictionaries inside the array based on the dueDate in ascending order, anyone have ideas?, I have tried with NSpredicate, with sortDescriptors but it isnt working, here is my sortDescriptors code:
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"dueDate" ascending:YES];
NSSortDescriptor *descriptor2 = [[NSSortDescriptor alloc] initWithKey:#"overDueDate" ascending:YES];
NSArray *descriptors = #[descriptor, descriptor2];
tasksResultArray = [tasksResultArray sortedArrayUsingDescriptors:descriptors];
Thanks in advance.
It can be done easier:
arrayOfDictionaries = [arrayOfDictionaries sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
// The logic for comparing dates, and returning the corresponding result
NSDate *date1 = (NSDate *) [(NSDictionary *)obj1 objectForKey:#"dueDate"];
NSDate *date2 = (NSDate *) [(NSDictionary *)obj2 objectForKey:#"dueDate"];
return [date1 compare:date2];
}];

Sorting JSON Data by date

Hi I'm getting data online from a JSON file and I'm trying to sort it by date in descending order, I've done it before using an XML parser using an RSS feed and tried to use the same concept but can't seem to get it and it crashes every time.
NSData *data = [NSData dataWithContentsOfURL:url];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSDictionary *dataDict = [dict objectForKey:#"data"];
NSArray *array = [dataDict objectForKey:#"items"];
for (int i=0; i<[array count]; i++) {
SongInfo *song = [[SongInfo alloc]init];
NSMutableDictionary *entry = [array objectAtIndex:i];
song.uploaded = [entry objectForKey:#"uploaded"];
song.uploader = [entry objectForKey:#"uploader"];
NSComparator comparator = ^(NSDictionary *a, NSDictionary *b) {
return [a[#"uploaded"] compare:b[#"uploaded"]];
};
NSUInteger index = [songsArray indexOfObject:entry
inSortedRange:NSMakeRange(0, [songsArray count])
options:NSBinarySearchingInsertionIndex
usingComparator:comparator];
[songsArray insertObject:song atIndex:index];
EDIT: Managed to fix it by using the NSSortDescriptor and putting it into an array and then back into the same array, not sure if there is a better way to do this but this is how I did it...
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"uploaded"
ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray;
sortedArray = [songsArray sortedArrayUsingDescriptors:sortDescriptors];
songsArray = [NSMutableArray arrayWithArray:sortedArray];
// [songsArray addObject:[song copy] atIndex:index];
[songsArray addObject:song];
You're comparing objects inserted in the songsArray with a comparator that takes in two dictionaries. It seems like the comparator should compare SongInfo objects rather than NSDictionaries.
We can't see what songsArray is. Creating a sorted array manually like you do is really inefficient. Call the NSArray method sortedArrayUsingComparator instead, and there is no need to create SongInfo objects.
On the other hand, if an array of SongInfo* is what you want, create that array first as an NSMutableArray with all the SongInfo's from the JSON data, then sort that array by calling sortUsingComparator.
Note that in the comparator block you can actually use the type of the object: So in the first case NSDictionary* instead of id, in the second case SongInfo* instead of id.

Sort NSMutableArray of objects by date

self.objectSet = [NSMutableArray array];
//add objects to set
[self.objectSet sortUsingComparator:^NSComparisonResult(id a, id b) {
NSDate *firstDate = [(Entity *)a createdAt];
NSDate *secondDate = [(Entity *)b createdAt];
return [secondDate compare:firstDate];
}];
I want to sort the nsmutablearray by createdAt date. However the above code has no effect on the displayed table view. The data is unsorted.
Any ideas whats wrong?
Did you try to sort with sort descriptors?
Is it the same effect?
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"createdAt" ascending:YES];
[self.objectSet sortUsingDescriptors:#[sortDescriptor]];

How to sort an array which contains Dictionaries?

I have an array which contains dictionaries in it; so how can I sort the array according to dictionary key values?
If every element in the array is a dictionary containing a certain key, you can sort the array using a sort descriptor. For instance, if every element is a dictionary containing a key called "name":
NSSortDescriptor *sortByName = [NSSortDescriptor sortDescriptorWithKey:#"name"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByName];
NSArray *sortedArray = [array sortedArrayUsingDescriptors:sortDescriptors];
The other way to achieve this would be using sortedArrayUsingComparator: method
NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [[obj1 valueForKey:#"value"] compare:[obj2 valueForKey:#"value"]];
}];
why don't you use a sorted dictionary where the property of sorted elements comes already with the data structure?
Please do check it out here
Hope this helps.
The above shared answer by Bavarious helped me.Just want to add one more thing.If you want to sort a mutable array use something like the below code
NSSortDescriptor *sortByName = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByName];
NSMutableArray *sortedArray = [[NSMutableArray sortedArrayUsingDescriptors:sortDescriptors]mutableCopy];
let arrDescriptor = NSSortDescriptor(key: "order", ascending: true)
let sortDescriptors: NSArray = [arrDescriptor]
let sortedArray = instancesubArray.sortedArray(using: sortDescriptors as [AnyObject] as [AnyObject] as! [NSSortDescriptor])
print(sortedArray)