Searching and Modifying NSMutableArray object with updated values - objective-c

I have constructed my model object with following.
#property (strong, nonatomic) NSString *id;
#property (strong, nonatomic) NSString *somevalue;
#property (strong, nonatomic) NSString *another value;
#property (strong, nonatomic) NSString *xtz;
#property (strong, nonatomic) NSString *st;
#property (strong, nonatomic) NSMutableArray *sc;
Now my mutable array is filled with following sample objects,
{a = 1;b = 6;c = 0;},{a = 2;b = 7;c = 0;},{a = 2;b = 8;c = 0;},{a = 3;b=9;c = 0;}
There are roughly 200 of such objects in my array. Now I cannot figure out a decent way of looping through the array updating the value of for example 'c' to '1' where 'a' ==1.
I could use a for loop like that:
for(int i = 0 ; i <myobject.sc.count; i++) {
NSLog(#"%#",[[myobject sc]objectAtIndex:i]);
}
It would allow me to iterate through the array. But still face the problem of looping through values contains within each object. Maybe a nested loop?

All you need is a simple loop:
for (WhateverDataType *data in myobject.sc) {
if (data.a == 1) {
data.c = 1
// break // uncomment if you only want to update the first match
}
}
This gives you a general idea for the solution. The specific syntax depends on what type of objects are actually in the mutable array.

Related

NSPredicate confusion with Nested Arrays of custom objects

I have a custom object, which is in the format:
#interface GroupModel : NSObject
#property (strong, nonatomic) NSString *groupId;
#property (strong, nonatomic) NSArray *children;
#property (strong, nonatomic) NSArray *instruments;
#property (strong, nonatomic) NSString *name;
#end
The instruments array is an array of custom models in the form of:
#interface InstrumentModel : NSObject
#property (strong, nonatomic) NSString *instrumentId;
#property (strong, nonatomic) NSString *name;
#end
And the children array in the GroupModel, is an array of GroupModel objects.
The reason behind this is to create a tree-like structure, so a root group can have multiple child groups, each of them can contain instruments and/or child groups.
Kinda like a folder/file format
Now what I'm trying is to search for a given instrument Id in a given GroupModel.
The instrumentId might be in the given model in the instruments array, or it might be in any children group models instruments array.
What kind of predicate would I need to be using, as I'm confused.
Would this require a subquery ?
Ok, This has worked for me:
//Create an array to add all InstrumentGroup Objects
NSMutableArray * allChildren = [NSMutableArray new];
//add the root group instruments
[allChildren addObjectsFromArray:rootGroup.instruments];
//now add the children's of children Instruments using the unionOfArrays Collection operator
[allChildren addObjectsFromArray:[rootGroup.children valueForKeyPath:#"#unionOfArrays.instruments"]];
//add the children's children instruments
[allChildren addObjectsFromArray:[rootGroup.children valueForKeyPath:#"#unionOfArrays.children.#unionOfArrays.instruments"]];
//filter the Instrument objects
predicate = [NSPredicate predicateWithFormat:#"ANY instruments.instrumentId == %#",selectedInstrumentId];
filtered = [allChildren filteredArrayUsingPredicate:predicate];
if (filtered.count>0) {
//found the instrument!
InstrumentModel *instrument = filtered.firstObject;
}

NSDictionary: Comparison after MutableCopy

I have the following properties:
#property (retain, nonatomic) NSMutableDictionary * firstStartTimeObject;
#property (retain, nonatomic) NSMutableDictionary * firstLocationNameObject;
#property (retain, nonatomic) NSMutableDictionary * firstLocationAddressObject;
#property (retain, nonatomic) NSMutableDictionary * secondStartTimeObject;
#property (retain, nonatomic) NSMutableDictionary * secondLocationNameObject;
#property (retain, nonatomic) NSMutableDictionary * secondLocationAddressObject;
//This is how I make copies of the Dictionaries:
-(DataClass *)copyObjects
{
DataClass *newClass = [[DataClass alloc]init];
newClass.firstStartTimeObject = [firstStartTimeObject mutableCopy];
newClass.firstLocationAddressObject = [firstLocationAddressObject mutableCopy];
newClass.firstLocationNameObject = [firstLocationNameObject mutableCopy];
newClass.secondStartTimeObject = [secondStartTimeObject mutableCopy];
newClass.secondLocationNameObject = [secondLocationNameObject mutableCopy];
newClass.secondLocationAddressObject = [secondLocationAddressObject mutableCopy];
return newClass;
}
//In another Class I compare them
if([myClass.firstStartTimeObject isEqualToDictionary:dataClass.firstStartTimeObject])
{
[dataClass.firstStartTimeObject setValue:kCellBackGroundColor forKey:kBackGround];
}
if([myClass.firstLocationNameObject isEqualToDictionary:dataClass.firstLocationNameObject])
{
[dataClass.firstLocationNameObject setValue:kCellBackGroundColor forKey:kBackGround];
}
if([dataClass.firstLocationAddressObject isEqualToDictionary:dataClass.firstLocationAddressObject])
{
[dataClass.firstLocationAddressObject setValue:kCellBackGroundColor forKey:kBackGround];
}
if([myClass.secondStartTimeObject isEqualToDictionary:dataClass.secondStartTimeObject])
{
[dataClass.secondStartTimeObject setValue:kCellBackGroundColor forKey:kBackGround];
}
if([myClass.secondLocationNameObject isEqualToDictionary:dataClass.secondLocationNameObject])
{
[dataClass.secondLocationNameObject setValue:kCellBackGroundColor forKey:kBackGround];
}
if([myClass.secondLocationAddressObject isEqualToDictionary:dataClass.secondLocationAddressObject])
{
[dataClass.secondLocationAddressObject setValue:kCellBackGroundColor forKey:kBackGround];
}
I have Break points setup. Keys/Values in comparing dictionaries is identical, but it seems like the compiler looks at them differently as the condition is never true for it to make it inside the braces and hit the breakpoint.
I verified the keys/values via NSLog and they are identical. I even tried protocol with - (id)mutableCopyWithZone:(NSZone *)zone and got the same behavior.
Does mutableCopy of an NSMutableDicitonary change its copy to where without changing any of its contents, you compare it to the source and it's not the same? I can't figure out what I'm doing wrong!
Two dictionaries have equal contents if they each hold the same number of entries and, for a given key, the corresponding value objects in each dictionary satisfy the isEqual: test. This is how equaltodictionary work .so the issue looks like your contents is not holding the same number of entries. Please recheck your mutabledictinary object. And one more thing i have noticed is that your one if condition where you are comparing same dataclass in-spite of having one myclass.

Using MagicalRecord, how do I get data out of NSArray and into a NSManagedObject?

I am using MagicalRecord to work with Core Data objects. I am having problems with retrieving Core Data objects using the NSArray that MR puts them into... I can't seem to get the data out of the array and into a NSManagedObject so I can work with it. Here is my code:
// create the predicate
NSArray *apptDataArray = [NSMutableArray new];
NSPredicate *predicate = ([NSPredicate predicateWithFormat:#"((aStartTime > %#) AND (aStartTime <= %#))", startDate, endDate]);
// find all appointments with that selected date
apptDataArray = [AppointmentInfo MR_findAllWithPredicate:predicate];
// now find the appointments for the selected date and put them in the schedule
if(apptDataArray.count > 0) {
for (NSManagedObject *AppointmentInfo in apptDataArray) {
NSLog(#"\n\n-->apptDataArray: %#", apptDataArray);
}
}
This is the definition for AppointmentInfo which is in a different class:
#interface AppointmentInfo : NSManagedObject
#property (nonatomic, retain) NSDate * aStartTime;
#property (nonatomic, retain) NSDate * aEndTime;
#property (nonatomic, retain) NSString * aServiceTech;
#property (nonatomic, retain) NSString * aApptKey;
#property (nonatomic, retain) NSDate *aShortDate;
Somehow, I need to get to the data which is in the returned array and place it in AppointmentInfo. I have tried all kinds of permutations, looked in Google and SO, but I couldn't find anything. I'm stumped! How do I do it?
I am not sure if I understand your problem correctly, but
the result apptDataArray of the fetch request is just an array of AppointmentInfo objects, so you can access individual objects with
AppointmentInfo *appt = [apptDataArray objectAtIndex:i]; // 0 <= i < apptDataArray.count
or enumerate all objects of the result array with
for (AppointmentInfo *appt in apptDataArray) {
NSLog(#"startTime=%#, endTime=%#", appt.aStartTime, appt.aEndTime);
}

Objective C, array operations

I am trying to do actions on array's elements but i really don't understand why my code doesn't work:
here is my .h:
#interface ViewController : UIViewController
{
NSArray *tableauScore;
UILabel * modificationScore;
}
#property (weak, nonatomic) IBOutlet UILabel *nom1;
#property (weak, nonatomic) IBOutlet UILabel *nom2;
#property (weak, nonatomic) IBOutlet UILabel *nom3;
#property (weak, nonatomic) IBOutlet UILabel *nom4;
#property (weak, nonatomic) IBOutlet UILabel *bsc1;
#property (weak, nonatomic) IBOutlet UILabel *bsc2;
#property (weak, nonatomic) IBOutlet UILabel *bsc3;
#property (weak, nonatomic) IBOutlet UILabel *bsc4;
#end
my .m:
tableauScore = [NSArray arrayWithObjects:nom4, nom3, nom2, nom1, bsc1, bsc2, bsc3, bsc4, nil];
for(int i = 0; i < 8; i++)
{
modificationScore = [tableauScore objectAtIndex:i];
modificationScore.hidden = NO;
modificationScore.center = CGPointMake(modificationScore.center.x, modificationScore.center.y -40);
}
The issue is that i have a thread point at "modificationScore = [tableauScore objectAtIndex:i];" line and I don't know why. I saw a lot of topics but no one can help me. Is anybody of you have an idea?
thank you!
I assume by "thread point" you mean a crash? If so, one of the properties you add to the array is probably nil.
Check the number of elements in the array ([tableauScore count]) before you loop over them; don't assume there are eight. Or, even better, use the syntax to loop over all elements:
for (a in tableauScore) {
I would not globally define modificationScore if you don't really need it.
I would do:
for(UILabel *tempLabel in tableauScore)
{
tempLabel.hidden = NO;
tempLabel.center = CGPointMake(modificationScore.center.x, modificationScore.center.y -40);
}
I don't know what you want to achieve with chaning the center, that needs to be changed
[NSArray arrayWithObjects:] will only create an NSArray up to the first nil given, so if one of the UILabels is nil you will not get an array of size 8 as you assume, but only an array containing the UILabels up to that point.
Since you have a hard coded loop size, you're probably ending up indexing outside of the array.
If you are changing objects in tableauScore you cannot use an NSArray because NSArray is immutable.
Use a NSMutableArray, reconfigure your labels and use replaceObjectAtIndex:withObject: to change them in the array.

Objective C - NSFetchRequest with category unique

I'm using Core Data for my iPhone app.
Initially I have a UITableViewController that just lists all the "Stores".
However, now we realized that list is getting too long, and would like to break it down into 2 layers of UITableViewController. The first one being "States" and the 2nd being the stores in the selected State.
I figured out how to grab all stores in a certain State
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"state.abbreviation == 'AA'"]];
How can I using NSFetchRequest, just to grab the list of States? Something like this sql statement maybe? Is it possible?
SELECT DISTINCT abbreviation FROM Stores;
Below is my Model (simplified)
Store.h
#class State;
#interface Store : ManagedAppObject {
#private
}
#property (nonatomic, retain) NSString * title;
#property (nonatomic, retain) State * state;
#end
State.h
#interface State : ManagedAppObject {
#private
}
#property (nonatomic, retain) NSString * abbreviation;
#property (nonatomic, retain) NSString * name;
#end
Thank you,
Tee
To get unique results you'd usually use
fetchRequest.propertiesToFetch = [NSArray arrayWithObject:#"<#propertyName#>"];
fetchRequest.returnsDistinctResults = YES;
fetchRequest.resultType = NSDictionaryResultType;
But unless I'm missing something here, that's probably not what you should do. Why don't you just set your fetchRequest to fetch State entities in the first place? Then use the state.stores relation (which hopefully you have modeled as the inverse of store.state) to get the data for your second 'layer' tableView.