Sort NSString of NSDate in iphone - iphone

I have an array which has NSString converted from NSDate. I am getting the initial index of the array and sorting them.
Dates are in format : 08AM , 01PM. When I try to do NSSortDescriptor, it always gives me 01PM and than 08AM.
//** Date string **//
NSDate *date1 = [dateFormat dateFromString:startSection];
[dateFormat setDateFormat:#"ah"];
startSection = [dateFormat stringFromDate:date1];
NSString *strSection = [NSString stringWithFormat:#"%#", startSection];
The string above is added in NSArray. The NSArray is used below to sort the strings. And finally, the same array is used to get the initial letter and display their index in sectionforsectionIndexTitle. So I have AM8 and PM1 as sections and not 8AM and 1PM.
NSSortDescriptor *nameDescriptor = [[[NSSortDescriptor alloc] initWithKey:#"start"
ascending:FALSE
selector:#selector(localizedCaseInsensitiveCompare:)] autorelease] ;
NSArray *descriptors = [NSArray arrayWithObject:nameDescriptor];
[[dict objectForKey:aKey] sortUsingDescriptors:descriptors];

How about using sortUsingComparator:? But this will involve changing the string from 08AM to AM08 and 01PM to PM01 before comparison so this assumes that they will be of that form.
NSMutableArray * theArray = [dict objectForKey:aKey]; /* To be sorted */
[theArray sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSString * string1 = [NSString stringWithFormat:#"%#%#", [(NSString *)obj1 substringFromIndex:2], [(NSString *)obj1 substringToIndex:2];
NSString * string2 = [NSString stringWithFormat:#"%#%#", [(NSString *)obj2 substringFromIndex:2], [(NSString *)obj2 substringToIndex:2];
return [string1 localizedCaseInsensitiveCompare:string2];
}];
/* theArray is now sorted */

Related

How to compare an array of NSStrings containing Dates in ascending order

I have an Array in which contains a list of dates represented as strings:
NSMutableArray *objArray=[[NSMutableArray alloc]init];
[objArray addObject:#"18-01-2013 2:51"];
[objArray addObject:#"16-01-2013 5:31"];
[objArray addObject:#"15-01-2013 3:51"];
[objArray addObject:#"17-01-2013 4:41"];
[objArray addObject:#"03-02-2013 3:21"];
[objArray addObject:#"05-01-2013 3:01"];
please tell me how to arrange this array in ascending order by using dates.
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:#"dd-MM-yyyy hh:mm"];
NSComparator compareDates = ^(id string1, id string2)
{
NSDate *date1 = [formatter dateFromString:string1];
NSDate *date2 = [formatter dateFromString:string2];
return [date1 compare:date2];
};
NSSortDescriptor * sortDesc = [[[NSSortDescriptor alloc] initWithKey:#"self" ascending:NO comparator:compareDates]autorelease];
[objArray sortUsingDescriptors:[NSArray arrayWithObject:sortDesc]];
By using this code i got exact output, thank you for all
we can do another way to get sorting array with dates
NSArray *objArr = [[NSArray alloc]initWithObjects:#"2003/08/02 03:00 ",#"2001/02/04 04:00 ",#"2001/02/04 05:00 ",#"2010/05/01 08:00 ",#"2002/12/02 02:00 ",#"2012/11/05 02:00 ",#"2013/10/01 12:00 ", nil];
NSArray *sortedArray = [objArr sortedArrayUsingComparator:^(id firstObject, id secondObject) {
return [(NSDate * )firstObject compare: (NSDate * ) secondObject];
}];
NSLog(#"sorteed Array %#",sortedArray);
NSSortDescriptor * descLastname = [[NSSortDescriptor alloc] initWithKey:#"active" ascending:YES];
[livevideoparsingarray sortUsingDescriptors:[NSArray arrayWithObjects:descLastname, nil]];
[descLastname release];
videoparsing = [livevideoparsingarray copy];
livevideoparsingarray is my array which I have sort & active is my tag which is in array which I have sort. You change with your requirements.
You can do this by using NSSortDescriptor
NSSortDescriptor* sortOrder = [NSSortDescriptor sortDescriptorWithKey: #"self" ascending: YES];
return [objArray sortedArrayUsingDescriptors: [NSArray arrayWithObject: sortOrder]];
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *str1 = #"18-01-2013";
NSString *str2 = #"16-01-2013";
NSString *str3 = #"15-01-2013";
NSString *str4 = #"17-01-2013";
NSString *str5 = #"03-02-2013";
NSString *str5 = #"05-01-2013";
NSArray *arr = [NSArray arrayWithObjects:str1, str2, str3,str4,str5 nil];
arr = [arr sortedArrayUsingFunction:dateSort context:nil];
NSLog(#"New dates %#",arr);
}
//The date sort function
NSComparisonResult dateSort(NSString *s1, NSString *s2, void *context) {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"dd-MM-yyyy"];
NSDate *d1 = [formatter dateFromString:s1];
NSDate *d2 = [formatter dateFromString:s2];
return [d1 compare:d2]; // ascending order
// return [d2 compare:d1]; // descending order
}
Try this
NSMutableArray *objArray;
objArray=[[NSMutableArray alloc] init];
[objArray addObject:#"18-01-2013 2:51"];
[objArray addObject:#"16-01-2013 5:31"];
[objArray addObject:#"15-01-2013 3:51"];
[objArray addObject:#"17-01-2013 4:41"];
[objArray addObject:#"03-02-2013 3:21"];
[objArray addObject:#"05-01-2013 3:01"];
NSSortDescriptor *sort_Date=[[NSSortDescriptor alloc] initWithKey:#"self"ascending:NO];
NSLog(#"%#",[[objArray sortedArrayUsingDescriptors:#[sort_Date]] description]);
I got below response
2013-02-06 11:23:35.100[1135:c07]
(
"18-01-2013 2:51",
"17-01-2013 4:41",
"16-01-2013 5:31",
"15-01-2013 3:51",
"05-01-2013 3:01",
"03-02-2013 3:21"
)

How to separate parts of NSString?

I have a NSMutableArray of NSStrings where each element of array has the format equal to #"key is 1::value is 1". Now I want to store string part coming before "::" in an array1 and string part coming after "::" in an array2. How can I do that?
Here is the Code :
NSArray *temp = [YourString componentsSeparatedByString:#"::"];
NSString *str1 = [temp objectAtIndex:0];
NSString *str2 = [temp objectAtIndex:1];
But prior to accessing the Objects in the Array .. check for whether it contains the value.
Try this ::
NSString *s = #"key is 1::value is 1";
NSArray *a = [s componentsSeparatedByString:#"::"];
NSLog(#" -> %# --> %#", [a objectAtIndex:0], [a objectAtIndex:1]);
use this:
[array1 addObject:[[YourString componentsSeparatedByString:#"::"] objectAtIndex:0]];
[array2 addObject:[[YourString componentsSeparatedByString:#"::"] objectAtIndex:1]];
The key to splitting your strings is to use the componentsSeparatedByString: method on NSString to separate your string into an NSArray. Read the docs on how this method acts with blank strings etc, but it's what you'd use.
You said you have an array of strings, so the basic implementation would involve iterating over that array and adding each element to the two other arrays.
NSMutableArray *arrayOfStrings = [NSMutableArray array];
NSMutableArray *array1 = [NSMutableArray array];
NSMutableArray *array2 = [NSMutableArray array];
for (NSString *string in arrayOfStrings)
{
NSArray *components = [string componentsSeparatedByString:#"::"];
if ([components count] == 2)
{
NSString *obj1 = [components objectAtIndex:0];
NSString *obj2 = [components objectAtIndex:1];
[array1 addObject:obj1];
[array2 addObject:obj2];
}
}
I found the way. I will keep adding the beforeString and afterString in array1 and array 2 respectively while iterating the elements of original array
for(int i=0;i<self.originalArray.count;i++)
{
NSString *temp=[self.originalArray objectAtIndex:i];
NSRange r = [temp rangeOfString:#"::"];
NSString *beforeString = [temp substringToIndex:r.location];
NSString *afterString = [temp substringFromIndex:r.location+2];
[array1 addObject:beforeString];
[array2 addObject:afterString];
}

How to sort plist by its value

I have Plist with list with List of Dictionaries(item0,item1,item2).and I populate this plist in the Graph..its works fine.and in Plist key (date)-> Value(i store by using NSDate) .Now I need to sort the Plist in such a way that:-
graph should display for only one week.
say if first value is 26-Dec-12 than only upto 1-Jan-13(1 week) values plist should display
.
code :
- (NSArray *)readFromPlist
{
// get paths from root direcory
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [documentPaths objectAtIndex:0];
NSString *documentPlistPath = [documentsDirectory stringByAppendingPathComponent:#"calori.plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:documentPlistPath];
valueArray = [dict objectForKey:#"title"];
return valueArray;
}
and
- (void)drawRect:(CGRect)rect {
// Drawing code
CGContextRef _context = UIGraphicsGetCurrentContext();
ECGraph *graph = [[ECGraph alloc] initWithFrame:CGRectMake(10,10, 480, 320)
withContext:_context isPortrait:NO];
NSMutableArray *Array=[NSMutableArray arrayWithArray:[self readFromPlist]];
NSMutableArray *items = [[NSMutableArray alloc] init];
for (id object in [Array reverseObjectEnumerator]){
if ([object isKindOfClass:[NSDictionary class]])
{
NSDictionary *objDict = (NSDictionary *)object;
tempItemi =[[ECGraphItem alloc]init];
NSString *str=[objDict objectForKey:#"title"];
NSLog(#"str value%#",str);
float f=[str floatValue];
NSString*str1=[objDict objectForKey:#"date"];
NSLog(#" str values2-- %#",str1);
tempItemi.isPercentage=YES;
tempItemi.yValue=f;
tempItemi.name=str1;
[items addObject: tempItemi];
}
}
[graph drawHistogramWithItems:items lineWidth:2 color:[UIColor blackColor]];
}
As your requirement is to filter date within 7 days,
I am giving you a logic, try this way:
- (NSArray *)readFromPlistForOneWeek {
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [documentPaths objectAtIndex:0];
NSString *documentPlistPath = [documentsDirectory stringByAppendingPathComponent:#"calori.plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:documentPlistPath];
//loop through each of the item
//and check if <8 then add that keyValue to array
NSMutableArray *tempValueArray=[NSMutableArray new];
for (NSDictionary *subDict in [dict objectForKey:#"title"]) {
// NSLog(#"=> %#",subDict);
NSString *plistDateString=[subDict objectForKey:#"date"];
NSDate *currentDate = [NSDate date];
NSDateFormatter *dateFormatter=[NSDateFormatter new];
[dateFormatter setDateFormat:#"dd-MMM-yy"];
NSDate *plistDate=[dateFormatter dateFromString:plistDateString];
NSString *currentDateString=[dateFormatter stringFromDate:currentDate];
NSTimeInterval secondsBetween = [plistDate timeIntervalSinceDate:currentDate];
NSInteger dateDiff = secondsBetween / 86400;
if( dateDiff<8 ){ //within 0-7 days
[tempValueArray addObject:subDict];
}
}
NSLog(#"valuArray : %#",tempValueArray);
return tempValueArray;
}
Have you tried with NSSortDescriptor?
NSSortDescriptor *sortDesc = [[NSSortDescriptor alloc] initWithKey:#"DATE" ascending:YES selector:#selector(compare:)];
[yourDictionary sortUsingDescriptors:[NSArray arrayWithObject:sortDesc]];
Try this
NSString *path = [[NSBundle mainBundle] pathForResource:#"yourfile" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
// sort it
NSArray *sortedArray = [[myDict allKeys] sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
// iterate and print results
for(NSString *key in sortedArray) {
NSLog(#"key=%#,value=%#", key, [dict objectForKey:key]);
}

how can I convert string to an array with separator?

I have a string in the following format
myString = "cat+dog+cow"
I need to store each string separated by + in to a array.
Eg:
myArray[0] = cat
myArray[1] = dog
myArray[2] = cow
Can anyone tell me the proper way to do this?
componentsSeparatedByString: splits the string and return the result in an array.
NSArray *myArray = [myString componentsSeparatedByString:#"+"];
[myArray objectAtIndex:0];//cat
[myArray objectAtIndex:1];//dog
[myArray objectAtIndex:2];//cow
Try this..
NSArray *arr = [myString componentsSeparatedByString:#"-"];
[arr objectAtIndex:0];//Hai
[arr objectAtIndex:1];//Welcome
It is vert simple..
NSString * test = #"Hello-hi-splitting-for-test";
NSArray * stringArray = [test componentsSeparatedByString:#"-"];
// Now stringArray will contain all splitted strings.. :)
Hope this helps...
I you don't want use array then iterate through each character...
NSMutableString * splittedString = nil;
for(int i=0;i<test.length;i++){
unichar character = [test characterAtIndex:0];
if (character=='-') {
if (splittedString!=nil) {
NSLog(#"String component %#",splittedString);
[splittedString release];
splittedString = nil;
}
} else {
if (splittedString==nil) {
splittedString = [[NSMutableString alloc] init];
}
[splittedString appendFormat:#"%C",character];
}
}
if (splittedString!=nil) {
NSLog(#"String last component %#",splittedString);
[splittedString release];
splittedString = nil;
}
Thats all...
NSArray *myWords = [myString componentsSeparatedByString:#"+"];
You can find this one very simple
NSString *str = #"cat+dog+cow";
NSArray *arr = [str componentsSeparatedByString:#"+"];
NSLog(#"Array items %#",arr);
OUTPUT:
Array items
(
Cat,
dog,
Cow
)
Use the componentsSeparatedByString: method of NSString.
NSString string = #"hai-welcome";
NSArray myArray = [string componentsSeparatedByString:#"-"];
NSString* haiString = [myArray objectAtIndex:0];
NSString* welcomeString = [myArray objectAtIndex:1];
NSArray *strArray = [myString componentsSeparatedByString:#"-"];
firstString = [strArray objectAtIndex:0];//Hai
secondString = [strArray objectAtIndex:1];//Welcome
This will be the solution if you are dealing with a string:
NSString *mySstring = #"hai-welcome";
NSMutableArray *anArray=[[NSMutableArray alloc] initWithArray:[componentsSeparatedByString: #"-"]];
And each word will be stored in respective position from 0-n.
Try This. :)
If you are averse to using arrays, you can consider this –
NSString *accessMode, *message;
NSScanner *scanner = [NSScanner scannerWithString:#"hai-welcome"];
NSCharacterSet *hyphenSet = [NSCharacterSet characterSetWithCharactersInString:#"-"];
[scanner scanUpToCharactersFromSet:hyphenSet intoString:&accessMode];
[scanner scanCharactersFromSet:hyphenSet intoString:nil];
[scanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:#""] intoString:&message];
NSArray *lines = [string componentsSeparatedByString:#"-"];
The first value will be stored in 0th index of lines and second value will be stored in 1th index of lines..
Why not array?
Simple code :
NSString *myString = [[NSString alloc] initWithString:#"cat+dog+cow"];
NSArray *resultArray = [tempString componentsSeparatedByString:#"+"];
NSLog(#"1. %# 2. %# 3. %#",[resultArray objectAtIndex:0],[resultArray objectAtIndex:1],[resultArray objectAtIndex:2]);
Try This:
NSString *str = #"cat+dog+cow" ;
NSArray *array = [str componentsSeparatedByString:#"+"];
NSLog(#"%#",array) ;

Working with NSDate and Comparing with Dates in Objective C

"31-Dec-2010 9:00AM to 1:00PM"
Take the above NSString for example, I need to convert it to 2 NSDates e.g.
31-Dec-2010 9:00AM AND 31-Dec-2010 1:00PM
Then compare it with the current Date to see if the current date falls within the given dates.
So 31-Dec-2010 10:00AM would fall within.
I'm wondering What are the best practices/tricks are with Objective C to do this elegantly?
As it turns out, NSDateFormatter has a dateFromString method, which does exactly what you want.
http://blog.evandavey.com/2008/12/how-to-convert-a-string-to-nsdate.html
The official documentation for NSDateFormatter:
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/Reference/Reference.html
I ended up doing it like so:
NSString *temp = [[dateString allValues] objectAtIndex:0];
NSLog(#"temp: %#", temp);
NSArray *tokens = [temp componentsSeparatedByString: #" "];
NSArray *tokenOneDelimited = [[tokens objectAtIndex:0] componentsSeparatedByString: #"-"];
NSString *dateStr1 = [NSString stringWithFormat: #"%#-%#-%# %#", [tokenOneDelimited objectAtIndex:2],
[tokenOneDelimited objectAtIndex:1],
[tokenOneDelimited objectAtIndex:0],
[tokens objectAtIndex:1]];
NSString *dateStr2 = [NSString stringWithFormat: #"%#-%#-%# %#", [tokenOneDelimited objectAtIndex:2],
[tokenOneDelimited objectAtIndex:1],
[tokenOneDelimited objectAtIndex:0],
[tokens objectAtIndex:3]];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"yyyy-MMM-dd hh:mma"];
NSDate *myDate1 = [dateFormatter dateFromString: dateStr1];
NSDate *myDate2 = [dateFormatter dateFromString: dateStr2];
NSDate *currentDate = [NSDate date];
NSComparisonResult comparison = [currentDate compare: myDate1];
NSComparisonResult comparison2 = [currentDate compare: myDate2];
if (
comparison == NSOrderedDescending &&
comparison2 == NSOrderedAscending
)
{
NSLog(#"is On now");