I create a NSDictionary, I put there some few objects and keys. But the problem is that the keys is sorted as I understood by the first letters of the key. For example, I put "G", "B", "C". So it is sorting and displaying them as, "B", "C", "G". I would like to disable the sorting, how could I do this. I'm working with more complicated example, but I would like to keep the situation simple in my question.
Question: How I could disable sorting in NSDictionary or how could I sort the NSDictionary myself?
Thanks in advance!
As was stated by #Dan F, NSDictionary does not sort its entries. As was stated in the comment by #Hot Licks, NSDictionary puts its contents in arbitrary order. You should never assume anything about the order of entries in the dictionary. An NSArray is more appropriate for this kind of thing.
If you really want to display the contents of a dictionary in some pre-defined sort order, you can get a array of the keys ordered using the values they are associated with. The NSDictionary class has the keysSortedByValueUsingSelector: and keysSortedByValueUsingComparator: methods that support this. So if you wanted to control the display order by sorting the values into ascending order you could implement do something like this:
NSArray *orderedKeys = [myDictionary keysSortedByUsingSelector:#selector(caseInsensitiveCompare:)];
for (int i = 0; i < [sortedKeys count]; i++) {
NSString *key = [sortedKeys objectAtIndex:i];
NSLog(#"%# = %#", key, [myDictionary objectForKey:key]);
}
The results should show each entry in the dictionary, sorted by the values within each entry.
"Sorting" is not something an NSDictionary knows about, if you want the data to be in a particular order, you should be using an NSArray instead
Related
I populate an NSMutableDictionary with some Json, the problem is that even if the Json is ordered correctly the NSMutableDictionary reorder the values randomly (at least I don't know what's the logic behind it).
I tried to reorder the NSMutableDictionary using the following method but I still get the same result as the Json:
NSArray* sortedKeys = [theData allKeys];
NSMutableArray* orderHelper = [[NSMutableArray alloc] initWithArray:sortedKeys];
[orderHelper sortUsingComparator:^NSComparisonResult(NSString *str1, NSString *str2) {
return [str1 compare:str2 options:(NSNumericSearch)];
}];
NSMutableDictionary *sortedDictionary = [[NSMutableDictionary alloc] init];
for (NSString *key in orderHelper){
[sortedDictionary setObject:theData[key] forKey:key];
}
where theData is the first NSMutableDictionary containing the Json.
debugging I can see that the NSMutableArray gets ordered correctly but then on the for the NSMutableArray randomly reorders the items.
Does anyone have a solution for this?
Dictionaries (or Maps) are generally not an ordered data structure, and this is also the case for NSDictionary and the like. That means that the iteration order of your dictionary or the order of the allKeys array does not correspond to the insertion order of the associations you put into the dictionary.
So since the order is important to you, you have two options:
1) Use an OrderedDictionary implementation which does exactly that (preserve insertion order). There is none in the Objective-C standard library, but open-source alternatives are available.
2) Keep track of the order yourself in a separate NSArray in which you put the keys of your dictionary. Then, instead of iterating over your dictionary directly, you iterate over this array and read the corresponding values from the dictionary.
The internal order of a dictionary is entirely implementation-specific and of no value to you, since it might even be subject to changes. But very easily put, you can think about it the following way: The dictionary will assign a numerical value to each of your keys (e.g. foo is mapped to 0 and bar to 1. When you insert this key, it will add the value to a bucket at the corresponding numerical index. So regardless of the insertion order, foo will always end up in the first bucket, and bar will always end up in the second bucket. This is the order you can observe when subsequently iterating the dictionary.
I have created a NSMutableDictonary.
The problem is that I am getting all the keys sorted into an alphabetical order. Why is it like this?
I have just noticed this today (never checked this before). Is this the actual implementation of NSMutableDictonary? Is there any way I can get the key/values in the order I have declared?
Below is the code in the screenshot:
- (IBAction)OnBtnSubmit:(id)sender {
NSString *strUid=[[NSUserDefaults standardUserDefaults] objectForKey:#"UID"];
NSString *picData=[self imageToNSString:ProfileImage.image];
NSString *strComment=_commentTxt.text;
NSString *strUnit=_unitTxt.text;
NSMutableDictionary *parameters =[NSMutableDictionary dictionaryWithObjectsAndKeys:strUid,#"uid",strComment,#"comment",strUnit,#"unit_donate",#"hi",#"image",nil];
NSLog(#"parameters : %#",parameters);
My concern is, can I get the key/values in the order I have declared?
Like below:
NSMutableDictionary *parameters =[NSMutableDictionary dictionaryWithObjectsAndKeys:strUid,#"uid",strComment,#"comment",strUnit,#"unit_donate",#"hi",#"image",nil];
{
uid = 85;
comment= test;
unit_donate = 1;
image=hi;
}
I Need this exact order as on the web end there is an array that stores the value for all these key. I need to make sure image will always be in the 4th position.
But I'm curious to know, I have logged the dictionary that I have created; why it is showing in alphabetical order? Is this the actual order that my dictionary holds or is there any other reason?
Yes, It will be like that. But whatever the order is it should not concern with your logic as you are always going to fetch value baesd on key not the based on order.
I am pretty sure that dictionaries are not keeping track of the input order. How are you outputting the dictionary, looping through keys or just printing the dictionary?
If you know the order you want to retrieve the objects, you can create your own version of the keys array and loop through that to pull out the objects from the dictionary in your desired order
For more details do check how dictionary works
I have an array for users, I want create a contact list.
I'm sorting objects and keys alphabetically.
NSArray *sortedKeys = [[contactListDictionary allKeys] sortedArrayUsingSelector: #selector(caseInsensitiveCompare:)];
NSArray *objects = [contactListDictionary objectsForKeys:sortedKeys notFoundMarker:[NSNull null]];
After this, I can initialize dictionary again with sorted keys and
objects.
contactListDictionary = [NSMutableDictionary dictionaryWithObjects:objects forKeys:sortedKeys];
But it did not sorting keys and objects. They are mixing in NSMutableDictionary, what can I do for this situation ?
You can't do anything about this, that is, not in the way you are now trying to.
The NSDictionary class does not allow you to tell it in what order to store its keys; that's just not the way it is implemented.
But you already found out that you can get the keys, in the desired order, in an array. There should be no need for the dictionary itself to be ordered, its purpose is to give you a fast lookup mechanimsm, and it does. If you want, for example, to display the keys in order, simply create a (temporary) array created the way you already now how to.
I have this code
NSDictionary *tempDict = [NSDictionary dictionaryWithObjects:
[NSArray arrayWithObjects:#"authorId","authorName","authorDescription",#"image",nil] forKeys:
[NSArray arrayWithObjects:#"id",#"name",#"desc",#"image",nil]];
NSLog(#"%#",[tempDict description]);
and the output is
desc = authorDescription;
id = authorId;
image = image;
name = authorName;
You see that the dictionary is sorted by key, alphabetically, for some reason. This is not good for me, because I need to add this dictionary to a plist, and this plist already has some dictionaries with unsorted keys. So how can I avoid this sorting?
The sorting is due to [NSDictionary description], which is used by NSLog. It's not a fundamental feature of NSDictionary. If you access the keys through fast enumeration or [dictionary allKeys], you won't find it sorted.
But to your underlying question, if what you want is "unsorted" (random), then "sorted" is just one of the possible random sequences. If you really want unsorted, then sorted shouldn't matter because its a subset.
If sorting matters, then you don't mean "unsorted," you mean "some other sorted order, such as insertion order." If you need NSDictionary to be sorted in some way, you need to impose that by converting it into an NSArray.
It's not sorted. It's displaying in an arbitrary order. Add some more items and you'll probably see the order change.
(It's possible that, internally, the storage is, for some mad reason, actually sorted, but there's nothing you can do about that.)
here is my dictionary and its values
NSMutableDictionary *myDic=[NSMutableDictionary Dictionary];
[myDIC setObject:#""];
[myDIC setObject:string1 forKey:key1];
[myDIC setObject:string2 forKey:key2];
[myDIC setObject:string3 forKey:key3];
so up to here i have filled up my dictionary.now i want to read them through a for loop.
for (NSString *key in myDic ){
}
here is my problem! inside this loop the my first key will be key1 but i seems it start from the last key that i have set before!
is there anyone who can tell me why ? and how i can meet my expectation as what i explained?
NSDictionary is not an index base collection it's a Hashtable, and like all HashTable, the elements are store according to some logic base on some Hash that you don't know. If you look in the documentation for NSDictionary you will find a sentence that state that there is not guaranty about the order into which the item will be retrieve.
If you want your key to be retrieve in a specific order you will need to keep your keys in an NSArray, in the order that you want them.
Or you can sort your keys when you need them.
NSArray * allKeys = [myDict allKeys];
allKeys = [allKeys sortedArrayUsing// [see the documentation for all options][1] ];
I came across this problem before. The order of a specific element in NSArray of NSMutableArray is decided by its index.
But unlike NSArray or NSMutableArray,The elements order in NSMutableDictionary or NSDictionary is undefined and nobody knows because its mechanism.
I chose a paragraph from Mac OS X Developer Libary for you:
"Internally, a dictionary uses a hash table to organize its storage
and to provide rapid access to a value given the corresponding key.
However, the methods defined for dictionaries insulate you from the
complexities of working with hash tables, hashing functions, or the
hashed value of keys. The methods take keys directly, not in their
hashed form."