how to print the keys in the order in nsmutabledictionary ios - ios

I am getting a response from a server and I am saving it in a dictionary like this, I am using an NSMutableArray for this purpose.
{
a = "";
b = "";
c = "";
d = "";
}
I want to print the keys in the same order as they are returned from the server.
But when I print the keys the order is: c, d, a, b.
The code I am using is:
for(id key in dic){
nslog(#"%#",key);
}
How can I do this correctly?

By nature NSDictionary and NSMutableDictionary are unordered. You would not be able to do it this way. I would suggest storing the keys into an NSArray or NSMutableArray and then printing out the elements of the array in order.

Try to keep the response in an NSMutableArray, where each element is a simple NSDictionary with only one key-value pair.

NSMutableDictionary is unordered collection.You can make your own ordered dictionary subclass and adding the keys to array in order they come.
Have a look here is nice explanation how to make ordered dictionary.You can also use this link

NSDictionary and NSMutableDictionary are unordered collections.
But you can use OrderedDictionary.

Related

Sort NSDictionary keys according to NSArray elements

I have NSDictionary filled with many objects. I have sorted the keys in a desired pattern and now I have the keys only in a new NSArray. How to apply the changes so the order of the elements in the array to be reflected in the dictionary?
For ex. NSArray -> ["D" , "B" , "A" , "C"] this order I want to apply to the keys in the dictionary.
NSDictionary -> {{"A" : <something>} , {"B" : <something>} , {"C" : <something>} , {"D" : <something>}}
You don't. You iterate over the keys in the array and then pull out the data from the dictionary.
for (NSString *key in sortedKeys) {
id value = dictionary[key];
// do something...
}
If you need ordering you might consider using NSOrderedSet or rolling your own data structure to do this. For example, I have created data structures that use both NSIndexSet and NSDictionary to provide key/value storage with faster sorted enumeration.

Dictionary key-value using with array

I have an array and it has lots of dictionary's keys it comes from API. My array as follows
Dictionary keys array :
NSArray *arr = #[#"01", #"02", #"03"];
Dictionary with key-value pairs
NSDictionary *dic = #{#"01": #"Hero", #"02" : #"Enemy", #"03" : #"Boss"};
Basically i want to match array values corresponding to dictonary keys without using array. I found a solition about that but I don't want to use for-loop for every cell(I have a lots of cell). My solution is like that
for(NSString *item in arr) {
[convertedArr addObject:[dic valueForKey:item]];
}
NSLog(#"%#", [convertedArr componentsJoinedByString:#","]);
Asumme have an array like this (1,2,3) and dictionary looks like {1 = "a", 2 = "b", 3 = "c"} I just want to give an array and it should return dictionary values like this ("a","b","c")
Anybody should give me better approach without using array? Thanks.
You can replace your for-loop by
NSArray *convertedArr = [dic objectsForKeys:arr notFoundMarker:#""];
which is at least less code. (The notFoundMarker: is added for all keys
in the array which are not present in the dictionary. Your code would crash
in that situation.)
It might perform slightly better because it is a library
function. But I doubt that the difference is big, because in any case a dictionary
loopup is required for all keys in arr.

How to check if NSDictionay key has a value efficiently when creating XML

I am creating some XML in objective C, I know how to do it however there is the possibility that there could be 800+ values I might be putting into XML, which I am getting from a NSArray of NSDictionaries.
So I was wondering if there is an efficient way of checking for nill or null in a keyvalue that's of type NSString.
Currently this is what my code looks like:
NSMutableArray *xmlItems = [coreDataController readInstallForXML:selectedInstallID];
for (int i = 0; i < [xmlItems count]; i++) {
NSDictionary *currentXMLItem = [xmlItems objectAtIndex:i];
[xmlWriter writeStartElement:#"Items"];
[xmlWriter writeAttribute:#"insID" value:[currentXMLItem valueForKey:#"insID"]];
// there are about another 20 attributes I have to add here.
}
// then write end elemtent etc.
In the code above I have no added any checking but I was hoping someone might have something better for me than adding a bunch of if statements for each attribute.
You can use [NSDictionary allKeysForObject:] to get all keys for the 'nil' values, so you have a list of keys to ignore.
Generating 800 items is not necessarily 'much' or 'slow'. You don't want to do that on the main thread anyway, so just make sure you perform it as a background operation.
use the allKeys method on the NSDictionary to return an NSArray of keys; then iterate through that array and for each key retrieve the value from the dictionary and use one if statement to check the string before writing out the xml element

Sort array based on second array order

I have an array from a plist and each value contains an key and a string and a secondary array that I get from a json file online. I want to order the secondary array based on the keys in the first array.
I want to achieve something like this:
array1:
Item0 - EUR
- String
Item1 - USD
- String
Item2 - AUD
- String
etc
array2:
Item0 - AUD
- 123.242
Item1 - EUR
- 535.123
Item2 - USD
- 325.646
etc
I have the same key index on both but I want to get the value for the key index from array2 based on the order of the key index in array1.
I have researched online but I cannot find a suitable solution that I can understand how to implement it.
How can I implement this?
Here is the plist file - https://gist.github.com/iulianvarzaru/11c400ba1edf4a165082
And the json file - https://gist.github.com/iulianvarzaru/1915e02a9201c57f49b3
Given that the JSON file you've linked to doesn't contain an array but a dictionary, you can simply iterate over array1 from the plist file. Each element of that array is a dictionary with a "Cod" key and a "Descriere" key. Get the value for the "Cod" key and then simply use that value as the key into the dictionary from the JSON file.
NSDictionary* jsonFileDict = ...;
NSDictionary* jsonFileInnerDict = jsonFileDict[#"rate"];
for (NSDictionary* dict in array1)
{
NSString* code = dict[#"Cod"];
NSNumber* jsonNumber = jsonFileInnerDict[code];
// Do something with jsonNumber
}
It sounds like these are key-value pairs, in which case, you can convert it to a Map, and then do direct lookups.
If you can manipulate the JSON file as JSON, then it reduces a conversion, but may not be the most efficient implementation.
Caveats:
This method assumes that you wont have key overloading (which is possible in a numeric array, but not in a map)
This requires a conversion from one data structure to another
EDIT: (due to increased information by OP).
The JSON file you receive doesn't contain an array, it contains an object. Thus, all the values are direct-lookup. So, you can traverse your array in Obj-c, and directly access the corresponding values in the JSON.
Sorry about the lack of actual code-samples.
You are dealing with a dictionary in the response, not an array.
You should transform it to something like
{
#"currency": #"EUR",
#"value": 123.45
}
create and sort it it like
NSArray *keys = #[#"EUR",#"USD",#"AUD"];
NSDictionary *dict = #{#"AUD":#(123.242), #"EUR": #(535.123), #"USD": #(325.646)};
NSMutableArray *result = [#[] mutableCopy];
for (NSString *key in keys) {
[result addObject:#{#"value":dict[key], #"currency": key}];
}
NSLog(#"%#", result);
(
{
currency = EUR;
value = "535.123";
},
{
currency = USD;
value = "325.646";
},
{
currency = AUD;
value = "123.242";
}
)
Or write a model class that can handle this information.

appending strings to NSMutableArray in NSMutableDictionary

I need to append strings to an array kept inside of a dictionary each time a word matches a pattern of another word. The second line below (setObject) overwrites instead of appending.
The end result should be arrays in a dictionary where the the key(pattern) identifies many strings that fit that pattern.
NSMutableDictionary *eqClasses = [[NSMutableDictionary alloc] init];
[eqClasses setObject:tempWordStr forKey:wordPattern];
Is there an easy way to append?
Try this:
NSMutableArray* array = [eqClasses objectForKey:wordPattern];
if(!array) {
// create new array and add to dictionary if wordPattern not found
array = [NSMutableArray array];
[eqClasses setObject:array forKey:wordPattern];
}
[array addObject:tempWordStr];
You indicate that the values in the dictionary should be arrays, but it looks to me like eqClasses contains NSStrings (tempWordStr). Don't you need to create an NSArray to hold the NSStrings associated with a keyword and then make the array the value in the dictionary that corresponds to the keyword? If the dictionary already contains the key, you need to retrieve the array associated with the key, add the new string to the array, and then call setObject using the array with the key.

Resources