NSMutable Dictionary adding objects - objective-c

Is there a more efficient way to add objects to an NSMutable Dictionary than simple iteration?
Example:
// Create the dictionary
NSMutableDictionary *myMutableDictionary = [NSMutableDictionary dictionary];
// Add the entries
[myMutableDictionary setObject:#"Stack Overflow" forKey:#"http://stackoverflow.com"];
[myMutableDictionary setObject:#"SlashDotOrg" forKey:#"http://www.slashdot.org"];
[myMutableDictionary setObject:#"Oracle" forKey:#"http://www.oracle.com"];
Just curious, I'm sure that this is the way it has to be done.

NSDictionary *entry = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:acceleration.x], #"x",
[NSNumber numberWithDouble:acceleration.y], #"y",
[NSNumber numberWithDouble:acceleration.z], #"z",
[NSDate date], #"date",
nil];

If you have all the objects and keys beforehand you can initialize it using NSDictionary's:
dictionaryWithObjects:forKeys:
Of course this will give you immutable dictionary not mutable. It depends on your usage which one you need, you can get a mutable copy from NSDictionary but it seems easier just to use your original code in that case:
NSDictionary * dic = [NSDictionary dictionaryWith....];
NSMutableDictionary * md = [dic mutableCopy];
... use md ...
[md release];

Allow me to add some information to people that are starting.
It is possible to create a NSDictionary with a more friendly syntax with objective-c literals:
NSDictionary *dict = #{
key1 : object1,
key2 : object2,
key3 : object3 };

NSMutableDictionary *example = [[NSMutableDictionary alloc]initWithObjectsAndKeys:#5,#"burgers",#3, #"milkShakes",nil];
The objects come before the keys.

Related

Sort NSMutableArray based on strings from another NSArray

I have an NSArray of strings that I want to use as my sort order:
NSArray *permissionTypes = [NSArray arrayWithObjects:#"Read", #"Write", #"Admin", nil];
I then have a NSMutableArray that may or may not have all three of those permissions types, but sometimes it will only be 2, sometimes 1, but I still want it sorted based on my permissionsTypes array.
NSMutableArray *order = [NSMutableArray arrayWithArray:[permissions allKeys]];
How can I always sort my order array correctly based on my using the permissionTypes array as a key?
I would go about this by creating a struct or an object to hold the permission types.
Then you can have...
PermissionType
--------------
Name: Read
Order: 1
PermissionType
--------------
Name: Write
Order: 2
and so on.
Then you only need the actual array of these objects and you can sort by the order value.
[array sortUsingComparator:^NSComparisonResult(PermissionType *obj1, PermissionType *obj2) {
return [obj1.order compare:obj2.order];
}];
This will order the array by the order field.
NSMutableArray *sortDescriptors = [NSMutableArray array];
for (NSString *type in permissionTypes) {
NSSortDescriptor *descriptor = [[[NSSortDescriptor alloc] initWithKey:type ascending:YES] autorelease];
[sortDescriptors addObject:descriptor];
}
sortedArray = [myArray sortedArrayUsingDescriptors:sortDescriptors];
Use whichever sorting method on NSMutableArray you prefer, you will either provide a block or a selector to use for comparing two elements. In that block/selector rather than comparing the two strings passed in directly look each up in your permissionTypes array using indexOfObject: and compare the resulting index values returned.
I suggest you another approuch:
- (void)viewDidLoad
{
[super viewDidLoad];
arrayPermissions = [[NSMutableArray alloc] init];
NSDictionary *dicRead = [NSDictionary dictionaryWithObjectsAndKeys:
#"Read", #"Permission", nil];
NSDictionary *dicWrite = [NSDictionary dictionaryWithObjectsAndKeys:
#"Write", #"Permission", nil];
NSDictionary *dicAdmin = [NSDictionary dictionaryWithObjectsAndKeys:
#"Admin", #"Permission", nil];
NSLog(#"my dicRead = %#", dicRead);
NSLog(#"my dicWrite = %#", dicWrite);
NSLog(#"my dicAdmin = %#", dicAdmin);
[arrayPermissions addObject:dicRead];
[arrayPermissions addObject:dicWrite];
[arrayPermissions addObject:dicAdmin];
NSLog(#"arrayPermissions is: %#", arrayPermissions);
// create a temporary Dict again
NSDictionary *temp =[[NSDictionary alloc]
initWithObjectsAndKeys: arrayPermissions, #"Permission", nil];
// declare one dictionary in header class for global use and called "filteredDict"
self.filteredDict = temp;
self.sortedKeys =[[self.filteredDict allKeys]
sortedArrayUsingSelector:#selector(compare:)];
NSLog(#"sortedKeys is: %i", sortedKeys.count);
NSLog(#"sortedKeys is: %#", sortedKeys);
}
hope help

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];

Objective-c SBJSONWriter convert array of dictionaries to JSON

I'm having some trouble with SBJsonWriter at the moment.
I need to send a request that contains a json object of name/value pairs. e.g.
[{%22uid%22:1,%22version%22:1}]
I can't figure out how to do this in Obj-C with the SBJson Writer framework.
For each pair I have tried to construct a dictionary then add the dictionary to an array. This results in an array containing many dictionaries, each containing one name/value pair.
Any idea on how a fix for this or is it possible?
Thanks in advance
To produce an Objective-C structure equivalent to the above JSON you should do this:
NSArray* json = [NSArray arrayWithObject: [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt: 1], #"uid",
[NSNumber numberWithInt: 1], #"version",
nil]];
Check my answer to the '' SBJsonWriter Nested NSDictionary '' question. it illustrates how to properly use SBJsonWriter.
It includes error check and some pieces of advise about SBJsonWriter behaviour with NSDate, float, etc..
Excerpt:
NSDictionary* aNestedObject = [NSDictionary dictionaryWithObjectsAndKeys:
#"nestedStringValue", #"aStringInNestedObject",
[NSNumber numberWithInt:1], #"aNumberInNestedObject",
nil];
NSArray * aJSonArray = [[NSArray alloc] initWithObjects: #"arrayItem1", #"arrayItem2", #"arrayItem3", nil];
NSDictionary * jsonTestDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
#"stringValue", #"aString",
[NSNumber numberWithInt:1], #"aNumber",
[NSNumber numberWithFloat:1.2345f], #"aFloat",
[[NSDate date] description], #"aDate",
aNestedObject, #"nestedObject",
aJSonArray, #"aJSonArray",
nil];

I am typing in text from a book for NSDictionary and get an error from it?

I typed in text from a book and
I get this error: Passing argument of 1 of "initWithObjects:forKeys:count:" from incompatible pointer type
NSDictionary *dict = [[NSDictionary alloc] initWithObjects: #"hello", #"there", #"persn"
forKeys: #"aa", #"bb", #"cc"
count: 3 ];
NSLog(#"%#", [dict objectForKey: #"bb"]);
In Objective-C, methods can't use var-args like that, they must always come at the end of the invocation.
In fact, the parameters to your message invocation are actually pointers to buffers of objects and keys.
Try this:
id objects[] = {#"hello", #"there", #"person"};
id keys[] = {#"aa", #"bb", #"cc"};
NSDictionary *dict1 = [[NSDictionary alloc] initWithObjects:objects forKeys:keys count:3];
NSLog(#"%#", [dict1 objectForKey: #"bb"]);

From array of dictionaries, make array containing values of one key

I have an array of dictionaries. I would like to extract an array with all the elements of one particular key of the dictionaries in the original array. Can this be done without enumeration?
Yes, use the NSArray -valueForKey: method.
NSArray *extracted = [sourceArray valueForKey:#"a key"];
Yes, just use Key-Value Coding to ask for the values of the key:
NSArray* names = [NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:
#"Joe",#"firstname",
#"Bloggs",#"surname",
nil],
[NSDictionary dictionaryWithObjectsAndKeys:
#"Simon",#"firstname",
#"Templar",#"surname",
nil],
[NSDictionary dictionaryWithObjectsAndKeys:
#"Amelia",#"firstname",
#"Pond",#"surname",
nil],
nil];
//use KVC to get the names
NSArray* firstNames = [names valueForKey:#"firstname"];
NSLog(#"first names: %#",firstNames);