formatting dictionary values - objective-c

I am needing to store values in a dictionary in the following format:
{ "UserId": 123,
"UserType": "blue",
"UserActs": [{
"ActId": 3,
"Time": 1
}, {
"ActId": 1,
"Time": 6
}]
}
I know I'll need a dictionary for the intitial values and a nested one for the UserActs but I am unsure how to store seperate values for the same keys "ActId" and "Time". How would I go about adding them in the dictionary following this format?

This is the old, long winded, way of creating that dictionary (there is a new syntax, using Objective-C literals, however they are not mutable, so I chose this method):
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:[NSNumber numberWithInt:123] forKey:#"UserId"];
[dict setObject:#"blue" forKey:#"UserType"];
NSMutableArray *acts = [[NSMutableArray alloc] init];
[acts addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:3], #"ActId",
[NSNumber numberWithInt:1], #"Time",
nil]];
[acts addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:1], #"ActId",
[NSNumber numberWithInt:6], #"Time",
nil]];
[dict setObject:acts forKey:#"UserActs"];

You can also use the shorthand for arrays and dictionaries
NSDictionary * dictionary = #{ #"UserId": #123,
#"UserType": #"blue",
#"UserActs": #[#{
#"ActId": #3,
#"Time": #1
}, #{
#"ActId": #1,
#"Time": #6
}]
};

Related

Objective-C append dictionary to NSDictionary

i need to send data to server with NSDictionary. The data will be name, gender dll, is coming from text field. I know i can save one dictionary like this.
NSDictionary * = #{#"employee": #"EmpA",
#"gender":#"Male",
#"pob":#"SF",
#"age":#"27",
};
But i need to add multiple data because i have button that can repeat the form procedure. After that i will send the whole data to server based on format below.
"employee": [{
"name": "EmpA",
"gender": "Male",
"pob": "SF",
"age": 27
}, {
"name": "EmpB",
"gender": "Female",
"pob": "TX",
"age": 36
}]
How i can dynamically append the dictionary?
Thanks
Use an Array of dictionaries :
NSMutableArray *employees= [[NSMutableArray alloc] init];
for(//loop through the forms) {
NSDictionary *emp = #{#"name": #"EmpA",
#"gender":#"Male",
#"pob":#"SF",
#"age":#"27",
};
[employees addObject:emp];
}
NSDictionary *payload = #{#"employee": employees};
I dont have a mac at hand so forgive any syntax errors.
You need to create an array of dictionaries and insert it in your "employee" key. Something like this should work:
NSMutableDictionary *employee = [[NSMutableDictionary alloc]init];
NSMutableDictionary *emplyeeA = [#{#"name": #"EmpA", #"gender": #"Male", #"pob": #"SF", #"age": #"27"} mutableCopy];
NSMutableDictionary *emplyeeB = [#{#"name": #"EmpB", #"gender": #"Female", #"pob": #"TX", #"age": #"36"} mutableCopy];
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
[tempArray addObject: emplyeeA];
[tempArray addObject: emplyeeB];
[employee setObject:tempArray forKey:#"employee"];

JSON string from NSMutableDictionary -

I wanted to generate a JSON string of the following format:
{
"test": {
"currency": "USD",
"gte": "100"
}
}
When I executed the following lines of code:
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
[tempArray addObject:tempDict];
[tempArray addObject:subDict];
[dict setObject:tempArray forKey:#"test"];
I retrieved this JSON string.
{
"test": [{
"currency": "USD"
}, {
"gte": "100"
}]
}
Any idea where I'm going wrong?
You must do it like this instead:
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] init];
[tempDict setObject: #"USD" forKey: #"Currency"];
[tempDict setObject: #"100" forKey: #"gte"];
[dict setObject:tempDict forKey:#"test"];
From your current try you are adding array of dictionary to dictionary so its display like
{"test":[{"currency":"USD"},{"gte":"100"}]}
You need to add dictionary,
Try Following,
NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:
tempDict,
subDict,
nil];
NSDictionary *final=#{#"test": dict};
How about this?
NSMutableDictionary *dic = [#{} mutableCopy];
NSMutableDictionary *tempDic = [#{} mutableCopy];
tempDic[#"currency"] = #"USD";
tempDic[#"gte"] = #"100";
[dic setObject:dic forKey:#"test"];
Modern Objective-C style..
Try like this:-
NSDictionary *yourDict = #{#"test": #{#"currency": #"USD",#"gte": #"100"}};

Using NSPredicate to filter based on multiple keys (NOT values for key)

I have the following NSArray containing NSDictionary(s):
NSArray *data = [[NSArray alloc] initWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:1], #"bill", [NSNumber numberWithInt:2], #"joe", nil],
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:3], #"bill", [NSNumber numberWithInt:4], #"joe", [NSNumber numberWithInt:5], #"jenny", nil],
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:6], #"joe", [NSNumber numberWithInt:1], #"jenny", nil],
nil];
I am wanting to create a filtered NSArray that only contains objects where the NSDictionary matches multiple 'keys' using NSPredicate.
For example:
filter the array to only contain the NSDictionary objects that have keys "bill" and "joe" [desired result: new NSArray would contain the first two NSDictionary objects]
filter the array to only contain the NSDictionary objects that have keys "joe" and "jenny" [desired result: new NSArray would contain the last two NSDictionary objects]
Can anyone please explain the format of the NSPredicate to achieve this?
Edit:
I can achieve a similar outcome to desired NSPredicate using:
NSMutableArray *filteredSet = [[NSMutableArray alloc] initWithCapacity:[data count]];
NSString *keySearch1 = [NSString stringWithString:#"bill"];
NSString *keySearch2 = [NSString stringWithString:#"joe"];
for (NSDictionary *currentDict in data){
// objectForKey will return nil if a key doesn't exists.
if ([currentDict objectForKey:keySearch1] && [currentDict objectForKey:keySearch2]){
[filteredSet addObject:currentDict];
}
}
NSLog(#"filteredSet: %#", filteredSet);
I'm imagining NSPredicate would be more elegant if one exists?
they only way I know is to combine two conditions like "'value1' IN list AND 'value2' IN list"
self.#allKeys should return all the keys of the dictionary (self is each dictionary in your array). If you don't write it with the prefix # then the dictionary will just look for a key that is "allKeys" instead of the method "- (NSArray*) allKeys"
The code:
NSArray* billAndJoe = [data filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"%# IN self.#allKeys AND %# IN self.#allKeys" , #"bill",#"joe" ]];
NSArray* joeAndJenny = [data filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"%# IN self.#allKeys AND %# IN self.#allKeys" , #"joe",#"jenny" ]]
Since a dictionary just returns nil if you ask for a value of a non-existing key, it is enough to specify that the value should be non-nil. A format like the following should cover your first case:
[NSPredicate predicateWithFormat: #"%K != nil AND %K != nil", #"bill", #"joe"]
The second case, with "joe" and "jenny" follows a similar pattern, of course.

Which type I should use to save many objects with same key? (iOS)

Which type I should use to save many objects with same key?
I should post data to server where one of parameter is suggestedTo and it contains userId.
This parameters should be more then one. So I'm confused which data type I should use to save them.
For example array or dictionary should looks like
{
#"suggestedTo" = 111,
#"suggestedTo" = 222,
#"suggestedTo" = 333,
etc.
}
This is typically handled with a dictionary of sets (or arrays if the data is ordered). So in this case, you'd have something like:
NSSet *suggestedTo = [NSSet setWithObjects:[NSNumber numberWithInt:111],
[NSNumber numberWithInt:222],
[NSNumber numberWithInt:333], nil];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:suggestedTo,
#"suggestedTo", nil];
You could use a dictionary of arrays
NSArray *suggestedTos = [[NSArray alloc] initWithObjects:
[NSNumber numberWithInt:111],
[NSNumber numberWithInt:222],
[NSNumber numberWithInt:333], nil];
NSDictionary *myDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:
suggestedTos, #"suggestedTo", nil];

sorting 2D arrays in Objective C

I'm stuck with sorting 2D arrays in objective c. I have a 2D array which I made from two string arrays.
NSArray *totalRatings = [NSArray arrayWithObjects:namesArray,ratingsArray,nil];
I've pulled the values using:
for (int i=0; i<2; i++) {
for (int j=0; j<5; j++) {
NSString *strings = [[totalRatings objectAtIndex:i] objectAtIndex:j];
NSLog(#"i=%i, j=%i, = %# \n",i,j,strings);
}
}
Firstly, I wonder whether there is a more elegant method for working with the length of the totalRatings array. Secondly, here is what the totalRatings array contains:
Person 1, 12
Person 2, 5
Person 3, 9
Person 4, 10
Person 7, 2
Since these are all strings, how can these be sorted? I'm looking for:
Person 1, 12
Person 4, 10
Person 3, 9
Person 2, 5
Person 7, 2
I'd appreciate any help you can provide.
You may want to use a dictionary to deal with this data, instead of two distinct arrays.
Instead of what you have now, why don't you put the record for each person on a dictionary:
NSArray *totalRatings = [NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:#"Person 1", #"name", [NSNumber numberWithInt:12], #"rating", nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"Person 2", #"name", [NSNumber numberWithInt:5], #"rating", nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"Person 3", #"name", [NSNumber numberWithInt:9], #"rating", nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"Person 4", #"name", [NSNumber numberWithInt:10], #"rating", nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"Person 7", #"name", [NSNumber numberWithInt:2], #"rating", nil],
nil];
NSArray *sortedArray = [totalRatings sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"rating" ascending:NO]]];