How to sort date? - ios

i have array Like :
<__NSArrayM 0x79f3a4a0>(
{
"act_date" = "02/03/2015";
"act_id" = 3;
"act_name" = test2;
},
{
"act_date" = "03/03/2015";
"act_id" = 4;
"act_name" = test3;
},
{
"act_date" = "01/03/2015";
"act_id" = 5;
"act_name" = test1;
}
)
i want to sort array with date.
i tried this method :
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MM/dd/yyyy"];
NSMutableArray *tempArray = [NSMutableArray array];
for (NSString *dateString in tblList)
{
NSDate *date = [formatter dateFromString:[dateString valueForKey:#"act_date"]];
[tempArray addObject:date];
}
[tempArray sortUsingComparator:^NSComparisonResult(NSDate *date1, NSDate *date2) {
// return date2 compare date1 for descending. Or reverse the call for ascending.
return [date2 compare:date1];
}];
But it returns only array with date, how do I add my all data with sorted date array??

I would do this, if you need to convert the values of "act_date" to an proper NSDate before comparison:
NSDateFormatter *_dateFormatter = [[NSDateFormatter alloc] init];
[_dateFormatter setDateFormat:#"MM/dd/yyyy"];
NSArray *_yourOriginalArray = // ...
NSArray *_sortedArray = [_yourOriginalArray sortedArrayUsingComparator:^NSComparisonResult(NSDictionary * obj1, NSDictionary * obj2) {
return [[_dateFormatter dateFromString:[obj2 valueForKey:#"act_date"]] compare:[_dateFormatter dateFromString:[obj1 valueForKey:#"act_date"]]];
}];
then the _sortedArray will have the items sorted.

You are taking out Date from your array, it is not need, you can still sort array of dictionary by using method like below.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"act_date" ascending:YES];
NSArray *sortedArray = [tblList sortedArrayUsingDescriptors:#[sortDescriptor]];

You can use a simple NSSortDescriptor
NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"act_date" ascending:YES selector:#selector(compare:)];
array = [array sortedArrayUsingDescriptors:#[sortDescriptor]];
If you want you can add more descriptor to sort for instance by act_id. The priority is set by the oreder of sort descriptors in the array that you pass to the method -sortUsingDescriptor
[EDIT]
As pointed out by holex act_date is a string and it should be converted to NSdate by using NSDateFormatter. Or you will just sort strings.

I am sorting an array of dictionaries with date-
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"act_date" ascending:NO];
[mArrTimeline sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];

Try this code. May be useful to you.
NSString *strKey = #"act_date";
NSSortDescriptor *sortByName = [NSSortDescriptor sortDescriptorWithKey:strKey ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByName];
tempArr = (NSMutableArray *)[arr sortedArrayUsingDescriptors:sortDescriptors];

Related

Use Two NSSortDescriptor to filter array

I would like to sort an array using the dictionary values "Name" and "Count". It would be Name alphabetically and split the names up into two groupd based on count.
bigger than 0
Smaller than Equal 0
My current implementation looks like this however it dose not split the groups up correctly.
NSSortDescriptor *sortCountDescriptor = [[NSSortDescriptor alloc] initWithKey:#"count" ascending:NO];
NSSortDescriptor *sortNameDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
NSArray * sortDescriptors = [NSArray arrayWithObjects:sortCountDescriptor, sortNameDescriptor, nil];
NSArray *sortedArray = [myArrayToSort sortedArrayUsingDescriptors:sortDescriptors];
return [sortedArray mutableCopy];
If by grouping you mean making them separate arrays then you need an NSPredicate instead of NSSortDescriptor for count key.
Try this (from what I understood the array is filled with instances of NSDictionary so I used casting to it. If that assumption is incorrect, the NSPredicate isn't hard to change to some other type or to be made more generic with KVC):
NSSortDescriptor *sortNameDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:NO];
NSArray * sortDescriptors = [NSArray arrayWithObjects:sortNameDescriptor, nil];
NSArray *sortedArray = [myArrayToSort sortedArrayUsingDescriptors:#[sortNameDescriptor]];
NSPredicate *zeroOrLessPredicate = [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
if ([[((NSDictionary*)evaluatedObject) objectForKey:#"count"] integerValue] <= 0) {
return YES;
}
else {
return NO;
}
}];
NSArray *zeroOrLessArray = [sortedArray filteredArrayUsingPredicate:zeroOrLessPredicate];
NSPredicate *moreThanZeroPredicate = [NSCompoundPredicate notPredicateWithSubpredicate:zeroOrLessPredicate];
NSArray *moreThanZeroArray = [sortedArray filteredArrayUsingPredicate:moreThanZeroPredicate];

Sorting an array based on a compare model iOS

Student *s1 = [Student new];
s1.city = #"Delhi";
Student *s2 = [Student new];
s2.city = #"Mumbai";
NSArray *arrModels = #[s1,s2];
NSArray *arrCompareModel = #[#"Mumbai",#"Delhi"];
I need to sort the arrModels based on arrCompareModel.
All solutions in web are related to ascending. But here I have a custom model.
How do I achieve it?
You need to write this for sorting descending
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"city" ascending:false];
NSArray *sortedArray = [arrModels sortedArrayUsingDescriptors:#[sortDescriptor]];
Try something like that:
NSArray *sortedArray = [arrModels sortedArrayUsingComparator:^NSComparisonResult(Student *obj1, Student *obj2) {
return [arrCompareModel indexOfObject:obj1.city] < [arrCompareModel indexOfObject:obj2.city];
}];

sort elements in NSArray based on timestamp of element in my case

I have an array of NSString, each NSString element contains a timestamp (epoch time) and other characters, e.g.: "time:1474437948687, <other characters>".
NSArrary *myData = [self loadData];// my array
So, myData looks like this inside:
{"time:1474437948687,fajlsfj...",
"time:1474237943221, axsasdfd...",
"time:1474681430940, someother...",
...
}
I need to have an array which contains the same elements as the above array, but are sorted in descending order of the timestamp. How can I do it?
I get stuck with iterating over the array of NSString:
for (NSString element in myData) {
...
}
Use following sortedArrayUsingComparator it will work for me : I use static data e.g time:1474437948687, ..
**time:1474437948687, <other characters> Consider String Format..**
NSArrary *myData = [self loadData];
NSArrary *sortedmyData = [[myData sortedArrayUsingComparator: ^(id obj1, id obj2) {
NSDateFormatter *df = [[NSDateFormatter alloc] init];
// Change Date formate accordingly ====
[df setDateFormat:#"dd-MM-yyyy"];
NSDate *d1 = [df dateFromString:[self sperateDate:obj1]];
NSDate *d2 = [df dateFromString:[self sperateDate:obj2]];
return [d1 compare: d2];
}];
// This is function is developed as per time:1474437948687, Consider String Format..
- (NSString *)sperateDate : (NSString *)obj1 {
NSArray *arr = [obj1 componentsSeparatedByString:#","];
NSArray *arr1 = [arr[0] componentsSeparatedByString:#":"];
return arr1[1];
}
Update Compare with primitive type :
NSArray *myData = #[#"time:1474437948687,fajlsfj...",#"time:1474237943221, axsasdfd...",#"time:1474681430940, someother..."
NSArray *sortedmyData = [myData sortedArrayUsingComparator: ^(id obj1, id obj2) {
NSNumber *d1 = [NSNumber numberWithDouble:[[self sperateDate:obj1] doubleValue]];
NSNumber *d2 = [NSNumber numberWithDouble:[[self sperateDate:obj2] doubleValue]];
return [d1 compare: d2];
}];
Hope this help you...
Do let me know if you have any other query
Try this :
NSArray *timearray = #[#"time:1474437948687,fajlsfj...",
#"time:1474237943221, axsasdfd...",
#"time:1474681430940, someother..."];
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#""
ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [timearray sortedArrayUsingDescriptors:sortDescriptors];
NSLog(#"sortedArray %#",sortedArray);
Output:
sortedArray (
"time:1474681430940, someother...",
"time:1474437948687,fajlsfj...",
"time:1474237943221, axsasdfd..."
)
First of all it seems to be a good idea to transform the string into instances of an entity type that reflects the data in a key-value manner. Then you can sort it easily by using an instance of NSSortDescriptor:
NSSortDescriptor *timeSorter = [NSSortDescriptor sortDescriptorWithKey:#"time" ascending:NO];
NSArray *sorted = [myData sortedArrayUsingSortDescriptors:#[timeSorter]];
However, you can sort the array as is by using a more complex sort descriptor:
NSSortDescriptor *timeSorter = [NSSortDescriptor sortDescriptorWithKey:#"self" ascending:NO comparator:
^(id one, id two )
{
NSString *timestamp1 = [one compenentsSepartedByString:#","][0];
timestamp1 = [timestamp1 substringFromIndex:5];
NSString *timestamp2 = [two compenentsSepartedByString:#","][0];
timestamp2 = [timestamp2 substringFromIndex:5];
return [timestamp1 compare:timestamp2 options:NSNumericSearch range:NSMakeRange(0, [timestamp1 length])];
}];
NSArray *sorted = [myData sortedArrayUsingSortDescriptors:#[timeSorter]];
Typed in Safari.

How to sort Custom array which contains date object

I have an NSArray which contains custom objects like this:
NSArray *array = {
students,students
}
And student object in turns store values like :
student.name,
student.class,
student.admissionDate
student.school ..etc
Now I want an NSArray which contains all the student's detail sorted in based on their admissionDate.
I tried using NSSortDecriptor but it doesn't helped me.
EDIT
After some hard work I have successfully formed a NSMutable array of NSDictionary which Looks like:
for(Student *arr in array)
{
NSMutableDictionary *dict;
dict = [[NSMutableDictionary alloc]init];
[dict setObject:arr.stuName forKey:#"name"];
[dict setObject:arr.stuAdate forKey:#"date"];
[dict setObject:arr.stuClass forKey:#"class"];
[expenseArray addObject:dict];
}
Printing description of expenseArray:
<__NSArrayM 0x7fe703833f70>(
{
name = uuu;
Adate = "2015-10-10 10:56:03 +0000";
class = 1st;
},
{
name = abc;
Adate = "2015-10-07 11:10:00 +0000";
class = 3rd;
},
{
name = btw;
Adate = "2015-10-10 11:13:47 +0000";
class = 4th;
}
)
Now how can i sort based on date
The sort descriptor should work for you
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"admissionDate" ascending:YES];
NSArray *sortedStudents = [studentArray sortedArrayUsingDescriptors:#[sortDescriptor]];
Below is the working example
NSMutableArray *studentArray = [NSMutableArray new];
for (int i = 0; i < 8; i++) {
Student *student = [Student new];
unsigned int randomInterval = arc4random();
student.admissionDate = [NSDate dateWithTimeIntervalSinceNow:randomInterval];
[studentArray addObject:student];
}
for (Student *student in studentArray) {
NSLog(#"%#", student.admissionDate);
}
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"admissionDate" ascending:YES];
NSArray *sortedStudents = [studentArray sortedArrayUsingDescriptors:#[sortDescriptor]];
NSLog(#"\n\n * * * * * After Sorting * * * * * *\n\n");
for (Student *student in sortedStudents) {
NSLog(#"%#", student.admissionDate);
}
Logs
2024-02-11 23:47:47 +0000
2093-11-13 21:49:48 +0000
2042-04-06 23:53:28 +0000
2032-12-23 01:49:46 +0000
2102-12-28 23:08:06 +0000
2058-10-17 14:14:27 +0000
2142-02-01 07:19:34 +0000
2048-05-14 07:07:04 +0000
* * * * * After Sorting * * * * * *
2024-02-11 23:47:47 +0000
2032-12-23 01:49:46 +0000
2042-04-06 23:53:28 +0000
2048-05-14 07:07:04 +0000
2058-10-17 14:14:27 +0000
2093-11-13 21:49:48 +0000
2102-12-28 23:08:06 +0000
2142-02-01 07:19:34 +0000
A sort descriptor should work fine
NSSortDescriptor *admissionSort = [NSSortDescriptor sortDescriptorWithKey:#"Adate" ascending:NO];
NSArray *sortedArray = [array sortedArrayUsingDescriptors:#[admissionSort]];
will sort the array based on the admission date assuming that is actually a NSDate value.
Although NSSortDescription seems to be the best way to sort an array, here is alternative approach:
NSArray *studentsArray = #[someStudent1, someStudent2];
NSArray *sortedStudentsArray = [studentsArray sortedArrayUsingComparator:^NSComparisonResult(Student *student1, Student *student2) {
return [student1.admissionDate compare:student2.admissionDate];
}];
NSSortDescriptor works fine!
You should replace your mutable dictionary with Student class.
#interface Student : NSObject
#property NSString *name;
#property NSString *className;
#property NSString *schoolName;
#property NSDate *admissionDate;
#end
#implementation Student
#end
Uses of this class
Student *student1 = [[Student alloc] init];
student1.name = #"Name a";
student1.className = #"4th";
student1.schoolName = #"XYZ High school";
student1.admissionDate = [NSDate dateWithTimeIntervalSinceNow:60 * 60 * 24]; // 60 * 60 * 24 one day time interval in second
Student *student2 = [[Student alloc] init];
student2.name = #"Name b";
student2.className = #"5th";
student2.schoolName = #"XYZ High school";
student2.admissionDate = [NSDate date]; // current date
NSArray *array = [NSArray arrayWithObjects:student1,student2, nil];
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:#"admissionDate" ascending:YES];
NSArray *sortedArray = [array sortedArrayUsingDescriptors:#[descriptor]];
for (Student *student in sortedArray) {
NSLog(#"admissionDate %#", student.admissionDate);
}
Please keep in mind that [array sortedArrayUsingDescriptors:#[descriptor]] return sorted array, not rearranged array elements itself.
Hope this will work.

Sorting NSMutableArray with date in ios7

hi i am new in IOS i have one array name with array1. Each index of an array there is one dictionary with 4 different fields like name,date,marks,standard. these all values are in NSString format. i want to sort this array1 by date. so can any one help me to do this please
here below is some part of my code
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc]init];
NSString *myname = name.text;
NSString *marks= marks.text;
NSString *date=date.text;
NSString *address=address.text;
NSString *rID=rID.text;
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyMMdd"];
NSDate *date1 = [dateFormat dateFromString:date];
[tempDict setObject:myname forKey:#"name"];
[tempDict setObject:marks forKey:#"marks"];
[tempDict setObject:date1 forKey:#"date"];
[tempDict setObject:address forKey:#"address"];
[tempDict setObject:rID forKey:#"Rid"];
[array1 addObject:tempDict];
NSSortDescriptor *sortByDate = [NSSortDescriptor sortDescriptorWithKey:#"date"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByDate];
NSArray *sortedArray = [array1 sortedArrayUsingDescriptors:sortDescriptors];
If you want to sort your array with the date then you have to create NSDate object instead of NSString
NSDate *date = [dateFormatter dateFromString:date.text];
where dateFormatter is your NSDateFormatter
I think -sortUsingComparator: is the cleanest option.
[array1 sortUsingComparator: (id obj1, id obj2) {
return [[obj1 objectFoKey: #"date"] compare: [obj2 objectForKey: #"date"]];
}];
I dont know about the size of your array but if it is not something very big, you can do this:
make a dictionary (we call it sortingDict) with number of index (in array1) as key and your date of the corresponding array object as the value. You should iterate through your array1 to do this of course. (it would be better if you create NSDate objects of your string dates by the way).
get sortingDict all values. ([sortingDict allValues]) We call this dateArray.
sort your date array using NSSortDescriptor or any other algorithm you may want to use. We call it sortedDateArray.
now in a for loop iterating through sortedDateArray you get the keys of your sortingDict in order (You can use [sortingDict allKeysForObject:] and put it in an array sortedIndices
now you have an array with indices of array1 in your desired sorted order.
reordering your initial array1 wouldn't be a problem I believe.
P.S: This is a very inefficient way that just got out of the top of my head, hope it helps.
you can do like this.. if you wanted to display in tableview than other arrays are useful.
if(array1 > 0)
{
NSMutableArray *UniqueDates = [array1 valueForKeyPath:#"#distinctUnionOfObjects.date"];
[recordDates addObjectsFromArray:UniqueDates];
NSArray *cleanedArray = [[NSSet setWithArray:recordDates] allObjects];
recordDates = [cleanedArray mutableCopy];
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"self" ascending:NO];
[recordDates sortUsingDescriptors:[NSArray arrayWithObjects:descriptor, nil]];
[mainarray addObjectsFromArray:array1];
}
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"date == %#", [recordDates objectAtIndex:YourIndex]];
// yourindex == indexpath.row if you are displaying in table view
NSArray *filterContacts= [array1 filteredArrayUsingPredicate:predicate];
mainarray = [filterContacts mutableCopy];
recordDates and mainarray is also mutablearray.

Resources