mutable array value getting empty - ios

I am having an array which contains a date. this is my array.
"2015-03-01",
"2015-03-04",
"2015-03-05",
"2015-03-06",
"2015-03-07",
"2015-03-08",
"2015-03-14",
"2015-03-15"
list the value according to this date.my coding is
NSArray * datevalue = [tempArr valueForKey:#"match_formatted_date"];
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"self" ascending:YES];
NSArray *descriptors = [NSArray arrayWithObject: descriptor];
NSArray *reverseOrder = [datevalue sortedArrayUsingDescriptors:descriptors];
NSPredicate *findFutureDates = [NSPredicate predicateWithBlock: ^BOOL(id obj, NSDictionary *bind){
NSDateFormatter *df = [[NSDateFormatter alloc]init];
[df setDateFormat:#"yyyy-MM-dd"];
[df setTimeZone:[NSTimeZone systemTimeZone]];
NSDate *dd = [df dateFromString:(NSString *)obj ];
return ([[NSDate date] compare:dd] == NSOrderedAscending);
}];
NSArray * arrFutureDates = [reverseOrder filteredArrayUsingPredicate: findFutureDates];
NSLog(#"arrFutureDates:%#",arrFutureDates);
for (id item in arrFutureDates)
{
if (![dataArr containsObject:item])
[dataArr addObject:item];
}
[dataArr sortUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
for (int i= 0; i<[dataArr count]-1; i++) {
for (id item in tempArr)
{
if([#"Mexico: Copa Mexico - Clausura" isEqualToString:[item valueForKey:#"league_name"]]
||[#"Mexico: Liga De Ascenso - Clausura" isEqualToString:[item valueForKey:#"league_name"]]
||[#"Mexico: Primera Division - Clausura" isEqualToString:[item valueForKey:#"league_name"]])
if([[dataArr objectAtIndex:i]isEqualToString:[item valueForKey:#"match_formatted_date"]])
{
NSMutableDictionary *tempDic =[[NSMutableDictionary alloc]init];
[tempDic setValue: [item valueForKey:#"match_formatted_date"] forKey:#"match_formatted_date"];
[tempDic setValue: [item valueForKey:#"league_name"] forKey:#"league_name"];
if (![titleheader containsObject:tempDic])
{
[titleheader addObject:tempDic];
}}}}
my problem is: In title header null value is coming. were I made the mistake, can anyone help me.

Check your code, you didnt initialize titleheader anywhere. In that case it will be nil only.
Before checking condition, initialize and assign some value to titleheader.
Or else i dont know you missed to paste the code.

Unreadable formatting aside, there are few issues in your code, that may cause your problem:
NSArray* datevalue = [tempArr valueForKey:#"match_formatted_date"];
Name suggests, that tempArr is NSArray, however you are accessing it as NSDictionary. There is difference between methods -valueForKey: and -objectForKey:. Former is NSObject method related to KVC, while latter is NSDictionary method for accessing stored objects. They are frequently confused, because called on NSDictionary they behave in the same way.
for (int i= 0; i<[dataArr count]-1; i++) {
This for loop skips last object in dataArr, which - I assume - was not intended. This can be fixed by i < dataArr.count or i <= dataArr.count-1.
Another issue - not related to problem, but opportunity to learn:
NSMutableDictionary *tempDic =[[NSMutableDictionary alloc]init];
[tempDic setValue: [item valueForKey:#"match_formatted_date"] forKey:#"match_formatted_date"];
[tempDic setValue: [item valueForKey:#"league_name"] forKey:#"league_name"];
if (![titleheader containsObject:tempDic])
Objects in containers are stored and compared (by default) as references, thus -containsObject will always return NO - even if there were another NSDictionary with the same key-value pairs.

Related

IOS/Objective-C: Build NSDictionary from NSManagedObject

I am trying to build an NSDictionary from an NSManagedObject. I was under the impression that you could do this with: NSMutableDictionary *myDict;
[myDict setObject:self.title forKey:#"title"];
}
Because a dictionary cannot hold nil values, I am testing for nil first. However, when I verify using a break that properties have values, when I build the dictionary it is nil. It shows as nil using a breakpoint and logs to console as NULL. Would appreciate someone confirming that the following is a valid way to create a dictionary and, if so, why the dictionary would be nil?
NSString *title = #"Test";
NSNumber *complete = #1;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss";
NSString *lasttouchedstr =[dateFormatter stringFromDate:[NSDate date]];
NSMutableDictionary *myDict;
if (self.title.length>=1) {
[myDict setObject:self.title forKey:#"title"];
}
if (![self.complete isKindOfClass:[NSNull class]]) {
[myDict setObject:self.complete forKey:#"complete"];
}
if (![self.lasttouched isKindOfClass:[NSNull class]]) {
[myDict setObject:lasttouchedstr forKey:#"lasttouchedstr"];
}
NSLog(#"myDict is:%#",myDict)//Logs as NULL
return myDict;
Thanks in advance for any suggestions.
NSMutableDictionary *myDict; declares the value but does not initialize it. You need
NSMutableDictionary *myDict = [[NSMutableDictionary alloc] init];
Secondly, managed objects will not be returning a value of NSNull for any of their attributes. You need to check for != nil instead. See here for a nice explanation of the differences between nulls and nils.

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.

Sorting NSMutableArray that contains NSMutableDictionaries [duplicate]

This question already has answers here:
How do I sort an NSMutableArray with custom objects in it?
(27 answers)
Closed 7 years ago.
I'm trying to figure out the best/most efficient way to sort an array that contains n-number of dictionaries. One of the key/value pairs in each dictionary is a date field. After adding all the dictionaries to the array, I would like to sort the array by descending date order.
For example, I have code like this:
NSMutableArray *myArray = [[NSMutableArray alloc] init];
NSMutableDictionary *dictionary1 = [[NSMutableDictionary alloc] init];
NSDate *today = [NSDate date];
[dictionary1 setObject:today forKey:#"date"];
[dictionary1 setObject:#"Another value" forKey:#"anotherKey"];
[myArray addObject:dictionary1];
NSMutableDictionary *dictionary2 = [[NSMutableDictionary alloc] init];
NSDate *tomorrow = [[NSDate date] dateByAddingTimeInterval:60*60*24];
[dictionary2 setObject:tomorrow forKey:#"date"];
[dictionary2 setObject:#"Yet another value" forKey:#"anotherKey"];
[myArray addObject:dictionary2];
Now I need myArray to be sorted by descending date. (array index 0 should be the latest date)
Note: In my actual project, I'm not creating and adding the dictionaries in this way. But for example purposes to see how the date is stored in the dictionary, lets assume I've put these two into the array.
You can use NSSortDescriptors here:
NSMutableArray *myArray = [[NSMutableArray alloc] init];
NSMutableDictionary *dictionary1 = [[NSMutableDictionary alloc] init];
NSDate *today = [NSDate date];
[dictionary1 setObject:today forKey:#"date"];
[dictionary1 setObject:#"Another value" forKey:#"anotherKey"];
[myArray addObject:dictionary1];
NSMutableDictionary *dictionary2 = [[NSMutableDictionary alloc] init];
NSDate *tomorrow = [[NSDate date] dateByAddingTimeInterval:60*60*24];
[dictionary2 setObject:tomorrow forKey:#"date"];
[dictionary2 setObject:#"Yet another value" forKey:#"anotherKey"];
[myArray addObject:dictionary2];
NSSortDescriptor *sortDesciptor = [NSSortDescriptor sortDescriptorWithKey:#"date" ascending:NO];
//Create new sorted array
NSArray *sortedArray = [myArray sortedArrayUsingDescriptors:#[sortDesciptor]];
//Or sort your mutable one
[myArray sortUsingDescriptors:#[sortDesciptor]];
There are lots of ways to do this. You could use an NSSortDescriptor as Krivoblotsky says.
You can also use the NSMutableArray sortUsingComparator method. The code would look something like this:
[myArray sortUsingComparator
^(NSDictionary *obj1, NSDictionary *obj2)
{
return [obj1["date"] compare: obj2["date"]]
}
];
The sortUsingComparator method takes an NSComparator block.
An NSComparator takes two objects of type id, and returns an NSComparisionResult:
typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);
Since NSDate supports the compare method you can just write 1-line comparator block that fetches the date entry for each dictionary and returns the result of comparing them.

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.

Sort Objectsdictionnary

I have a tableview that contains multiple sections, grouped by an attribute of my object (date) I try to sort the tableview according to the value of date.I created a function for that , but I get an error :
- (void)sortObjectsDictionnary:(NSArray *)arrayObjects
{
//this is my nsdictionnary
[objects removeAllObjects]
//this is nsmutableaaray that contains dats
[objectsIndex removeAllObjects];
NSMutableSet *keys = [[NSMutableSet alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy/MM/dd"];
for(int i=0;i<[arrayObjects count];i++){
Task *myTask=[arrayObjects objectAtIndex:i];
//curentsection contains my objects whith dates
NSMutableArray *currentSection = [objects objectForKey:taskDate];
if (currentSection == nil)
{
[keys addObject:taskDate];
currentSection = [[[NSMutableArray alloc] init] autorelease];
[objects setObject:currentSection forKey:taskDate];
}
// we add objet to the right section
[currentSection addObject:myTask];
}
[dateFormatter release];
for (id element in keys)
{
[objectsIndex addObject:element];
NSMutableArray *currentSection = [objects objectForKey:element];
//I get an error in this line
[currentSection sortUsingSelector:#selector(compare:)];
}
You haven't mentioned what the error message is and I am assuming the error message may be due to accessing NSMutableArray array object without initializing it. Try an alloc and init for array before
NSMutableArray *currentSection = [NSMutableArray]alloc]init];
currentSection = [objects objectForKey:element];
//I get an error in this line
[currentSection sortUsingSelector:#selector(compare:)];
Well it is purely a guess. Post your error message if this not works.
Bharath

Resources