Add to NSMutableDictionary without replacing similar keys - ios

I am dynamically populating a NSMutableDictionary with keys that are identical. However doing so replaces the original keys value. What I require is it to be appended and not replacing the existing key. For example, I need a structure like
{
#"Key" : #"Value1",
#"Key" : #"Value2",
#"Key" : #"Value3"
}
I know I could add each NSDictionary that is created to a NSMutableArray but my issue comes because I need the input value to be a NSDictionary.
Currently I have the following which replaces the original value
NSMutableDictionary *ripDictionary = [[NSMutableDictionary alloc] init];
for(NSString *ripId in recievedRips){
//SOME OTHER CODE
ripDictionary[#"rip"] = keysAndAttributes;
[data addObject:ripDictionary];
}

From the NSDictionary Reference
A key-value pair within a dictionary is called an entry. Each entry consists of one object that represents the key and a second object that is that key’s value. Within a dictionary, the keys are unique. That is, no two keys in a single dictionary are equal (as determined by isEqual:).
Perhaps you could modify your code to accept a dictionary like:
{
#"Key" : [
#"Value1",
#"Value2",
#"Value3"
]
}

You can only have a single unique key per dictionary, so if you want multiple values associated with it then you would add those values to an array associated with the key.
if([aDictionary objectForKey:#"key"] != nil){
aDictionary[#"key"] = #[aDictionary[#"key"], bDictionary[#"key"]];
}else{
aDictionary[#"key"] = bDictionary[#"key"];
//OR make all aDictionary values array by default with a single value
//but you get the point
}

Related

Concatenate Strings for Dictionary:syntax error

The following code to conditionally concatenate strings for a dictionary seems to work up to the point where I try to place the concatenated result in the dictionary. Can anyone see the error?
NSDictionary *jsonDictionary;
NSString* dictString = #"#\"first\":first,#\"last"
NSString *dictString2=dictString;
if (date.length>0&&![date isKindOfClass:[NSNull class]]) {
//only include this key value pair if the value is not missing
dictString2 = [NSString stringWithFormat:#"%#%s", dictString, "#\"date\":date"];
}
jsonDictionary = #{dictString2}; //syntax error. Says expected colon but that does not fix anything
The syntax for creating an NSDictionary using object literals is:
dictionary = #{key:value}
(and optionally, it can contain multiple key/value pairs separated by commas, but never mind that right now.)
Where "key" and "value" are both NSObjects.
Your line that is throwing the error only contains 1 thing. The contents of a the string in dictString2 has nothing to do with it.
It looks to me like you are trying to build a JSON string manually. Don't do that. Use NSJSONSerialization. That class has a method dataWithJSONObject that takes an NSObject as input and returns NSData containing the JSON string. That's how you should be creating JSON output.
Creating an NSDictionary with values that may be null:
NSDictionary *dict = #{
#"key" : value ?: [NSNull null],
};
When serializing a dictionary, NSNulls are translated to null in the JSON.
If you want to exclude such keys completely, instead of having them with a null value, you'll have to do more work. The simplest is to use an NSMutableDictionary and test each value before adding it.

How to create dynamic NSDictionary to store multiple URLs with multiple keys?

I want to store multiple urls with it's name , websitename and rssfeed url .
How can I store it in dictionary ?
Like ,
My key is , #"nameoffeed", #"websitename", #"urlfeedname" I want to store all in dictionary related to url .
Like user search 3 feed then name , websitename and urlfeed all are stored in NSDictionary ?
How can I do this ?
I am using this , but it stores only 1 value .
//newdevice1 is my nsmanageobject
NSArray *keys = [[[newDevice1 entity] attributesByName] allKeys];
NSDictionary *singledict = [newDevice1 dictionaryWithValuesForKeys:keys];
I need this type of result in dictionary.
{
nameoffeed = "cnn" ;
websitename = "www.cnn.com";
urlfeedname = "www.cnn.com/feed";
nameoffeed = "nytimes" ;
websitename = "www.nytimes.com";
urlfeedname = "www.nytimes.com/feed";
}
you can do by this way.
NSDictionary *dic = #{#"nameoffeed":#"cnn",#"websitename":#"www.cnn.com",#"urlfeedname":#"www.cnn.com/feed"};
NSDictionary *dic2 = #{#"nameoffeed":#"nytimes",#"websitename":#"www.nytimes.com",#"urlfeedname":#"www.nytimes.com/feed"};
NSArray *dicArray = #[dic,dic2];
My key is , #"nameoffeed", #"websitename", #"urlfeedname" I want to
store all in dictionary related to url . Like user search 3 feed then
name , websitename and urlfeed all are stored in NSDictionary ?
Based on this, I believe you want a dictionary of dictionaries, where each sub-dictionary is indexed by the name.
In your example, you are already creating the dictionary for an individual object using dictionaryWithValuesForKeys.
All you need to do is add each one to a dictionary by the url key.
First, you need a mutable dictionary to add items to...
NSMutableDictionary *byURL = [[NSMutableDictionary alloc] init];
Then, for each item, grab the "url" you will use as a key...
NSString *name = [newDevice1 valueForKey:#"nameoffeed"];
and add the values to the dictionary
if (name) {
NSArray *keys = [[[newDevice1 entity] attributesByName] allKeys];
byURL[name] = [newDevice1 dictionaryWithValuesForKeys:keys];
}
You can then do the same thing for each object, resulting in a dictionary where you can look up each object by url.
NSDictionary *d = byURL[#"cnn"];
will give you the dictionary containing all the key/value pairs for "cnn"
If you want to end up with an immutable dictionary that is to be used strictly for searching (after adding everything you want to add), you can create an immutable copy...
NSDictionary *objectsByURL = [byURL copy];
In Dictionary we can save or store the multiple key values.But it must be the Different key.The Key name must not be the same.If use store the same key name in dictionary,it shows you error or your app crashes.But you can have the same values in dictionary.You have to store the different key name with multiple same values.
You can save the save the set of dictionaries to array like below
NSDictionary *dictFirstSet = [[NSDictionary alloc]initWithObjectsAndKeys:#"cnn",#"nameoffeed",#"www.cnn.com",#"websitename",#"www.cnn.com/feed",#"urlfeedname",nil];
NSDictionary *dictSecondSet = [[NSDictionary alloc]initWithObjectsAndKeys:#"nytimes",#"nameoffeed",#"www.nytimes.com",#"websitename",#"www.nytimes.com/feed",#"urlfeedname",nil];
NSArray *arrayDict = [[NSArray alloc]initWithObjects:dictFirstSet,dictSecondSet,nil];
NSLog(#"The arrayDict is - %#",arrayDict);
The output is
The arrayDict is - (
{
nameoffeed = cnn;
urlfeedname = "www.cnn.com/feed";
websitename = "www.cnn.com";
},
{
nameoffeed = nytimes;
urlfeedname = "www.nytimes.com/feed";
websitename = "www.nytimes.com";
}
)

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.

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