Get index for value NSDictionary - ios

I've got a value like so: #"2329300" and I've got a NSDictionary like so :{#"John Appleseed":[#"2329300",#"2342322",#"32i249"]}
How do I find the index of the key/value pair in the NSDictionary when I've only got a string value of the entire list that's known as the value. I'm assuming there's no duplicates in the dict.
I know that there's indexForObject on a NSArray but is there a similar thing for a dict?
I imagine it would look something like this:
[NSDictionary indexForValue:value]; // returns index number.
And even then the NSString doesn't match the value, so I'd need a workaround for that too.

You have a basic misunderstanding. Dictionaries are unordered collections. They do not have any particular order for their key/value pairs. You can't have indexes to the key/value pairs because that implies a fixed order.
Think of a dictionary as a bunch of kids milling around on a playground. You can call out a kid's name "Johnny, come here!" and fetch that kid (use a key to find an object) but what does order mean for kids that won't sit still?
You can create an array of the keys from a dictionary and sort that into a particular order (an alphabetical list of the kids on the playground) if that's what you want, or you can create an array of dictionaries, or an array of a custom data object that contains any arbitrary properties that you want.
EDIT:
For a table view, an array of dictionaries is probably a good choice. Each entry in the array contains a dictionary with all the settings for a cell in the dictionary. If you have a sectioned table view then you want an outer array for sections, containing inner arrays for the rows, and each entry in the inner array containing a dictionary.
I tend to prefer custom data objects to dictionaries though. (An object that just has properties for each setting I want.) That way the list of values and their types is crystal-clear and fairly self-documenting.

Related

Problems With sorting array data coming from json (all values)

I have 4 values coming from json (name, ratings, reviews and Qualifications). I want to sort this data using name, reviews and qualifications one by one. But when I sort this data then remaining values are not changing in array.
Here is my code.
_arrOfDoc_name = [_arrOfDoc_name sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
From comments:
I have to show four values on my screen which are coming from 4 different arrays. but when i sort one array then values of another arrays are not gng to sort and it displays wrong data on screen. how can i sort data of remaining arrays using its index path.
Ok, your comments explain what you're trying to do.
The best answer is to NOT use 4 different arrays. Restructure your data to have a single array that contains dictionaries. Then sort the array of dictionaries.
Failing that, you'll have to be clever. You might be able to create an array of indexes and sort that, or hand-write a sort routine that sorts all 4 arrays at once.

Best way to represent un-ordered data in a plist

I'm making a plist to hold genre synonyms. The list of synonyms for a given genre doesn't have any inherent order to it.
Should I use an array (which implies an order that doesn't exist) or a dictionary (which implies there's a corresponding value for each key, which doesn't exist).
Simply put--to store an unordered set in a plist, how should I represent it and why?
(To clarify: If there were a Set data structure in the plist editor, I would use that, but I only have Array and Dictionary to choose from.)
More details: I'm going to be looking up by the primary representation of the genre, thus the outer data structure in the plist has to be a dictionary.
But then for the synonyms, the only operation necessary is to enumerate them using a block.
So either an array or a dictionary will do. However, I'm concerned that using an array will imply an order that doesn't have any semantic meaning. On the other hand, is it a common occurrence to have dictionaries in plists that don't have a corresponding value?
Editing again to respond to Josh's comments:
I like your idea of converting into an NSSet after reading in the plist. However, I could still do that with a dictionary, right? So not sure why an array is the obvious choice.
If someone else edits the plist, they might think there's a meaning to the order, when in reality, the ordering is arbitrary.
Surprised no-one has defended using a dictionary instead of an array. Is there a reason a dictionary shouldn't be used in a plist for this purpose?
If you don't care about order, then the arbitrary order you get from building an array is equivalent to the arbitrary order you'd get by using a set. You can also very easily convert an array in a plist to an NSSet after reading it back: +[NSSet setWithArray:]
So use an array.
I would just use an array, since you say there's no corresponding key for a dictionary entry.
At the same time, if you're typing in a large number of entries into plist files (www), your fingers may get tired from dealing with the raw XML or plist editor stuff. You might want to consider a different way to save your synonyms?
Use an NSArray if lookup by item is not needed. If lookup is needed use an NSDictionary.

What is the relationship between elements of plists, arrays and dictionaries?

I've got a simple program that needs to log and persistently store 2 simple pieces of data produced each time the user selects an item in a table view. The two pieces of data are 1) the time of the tap (NSDate) and 2) the name of the item tapped (NSString). At this point, this information is in this form:
TimerEvent *latestTappedEvent = [[TimerEvent alloc] init];
latestTappedEvent.timeTapped = NSDate.date;
latestTappedEvent.activityTapped = tappedItem.itemName;
The two data pieces must remain associated with each other.
My question is this:
How do I get this data into and out of a plist, ordered chronologically?
In my research, I have only become more confused. It's just not obvious to me how to use a plist. Initially, I thought I could use an NSMutableDictionary with latestTappedEvent.timeTapped as a key, and latestTappedEvent.activityTapped as the value. But when I tried to construct the plist manually, it appears not to be possible, wanting instead a string for a key.
If anyone can help me understand this, preferably by giving a graphic representation of the relationship among these different elements, I would be forever grateful.
Dictionaries and arrays both store 'things' - and the things stored are retrieved and set by using 'something else' to do a 'lookup' on the data structure. In an array, that lookup is the index in the array where an object is stored. In tabular form:
Index Storage
0 "some string stored at index 0"
1 "some other string"
2 <some other object, stored at index 2>
To find "some string stored at index 0" you would need to know it's stored at index 0 and ask the array for the object at that index. So arrays use integers to look up objects stored in them, and these integers must be in the range of 0 to the array's count minus 1. The use of integers to look up items in the array also gives the array order - the top-to-bottom ordering you see in the table above is the same order that iterating in code would yield.
Dictionaries use arbitrary objects to do the lookup which also means there's no ordering in a dictionary, there's just a set of associations of keys and what they refer to. In tabular form:
Key Storage
"name" "a string that will be accessed using the key 'name'"
"number" <some numeric object, that will be accessed using the key 'number'>
<object> "will be accessed with key <object> which is an arbitrary object"
To get "a string that will be accessed using the key 'name'" from this dictionary, you ask the dictionary for what's stored under the key "name".
In the above examples, I gave the table heading "Index - Storage" or "Key - Storage", but to circle back to the point that these structures both store things hat are accessed using another thing, let's view the array with a more generic table:
Thing used to access the thing that's stored Thing that's stored
0 "some string stored at index 0"
1 "some other string"
2 <some other object, stored at index 2>
And again, the dictionary, with the same table:
Thing used to access the thing that's stored Thing that's stored
"name" "a string that will be accessed using the key 'name'"
"number" <some numeric object, that will be accessed using the key 'number'>
<object> "will be accessed with key <object> which is an arbitrary object"
Also, let's view your class TimerEvent in the same table:
Thing used to access the thing that's stored Thing that's stored
timeTapped <date object>
activityTapped "name of an activity"
The items in the left column are Objective-C property names, and the items on the right are the values those properties contain. Now, take another look at the dictionary - the items on the left are arbitrary values (in practice they are commonly strings) and the items on the right are other arbitrary values. Hopefully you can see the connection here - that you can generally represent an object's properties as a dictionary that maps the string representation of a property name to the value the property stores. So, if you want to represent the TimerEvent object in a dictionary, you'd end up with a representation like:
Key Object
"timeTapped" <date object>
"activityTapped" "activity name"
The tables above illustrate the commonalities and differences between arrays, dictionaries, and other objects, and show that using a dictionary to map property names to property values can represent the properties of any given object. So, how would the code to do this look? Let's say we want to represent the TimerEvent object timerEvent in an NSDictionary:
NSDictionary *timerEventRepresentation = #{ #"timeTapped": timerEvent.timeTapped,
#"activityTapped": timerEvent.activityTapped};
And here's how we could create a TimerEvent from a dictionary representation:
TimerEvent *timerEvent = [[TimerEvent alloc] init];
timerEvent.timeTapped = timerEventDictionaryRepresentation[#"timeTapped"];
timerEvent.activityTapped = timerEventDictionaryRepresentation[#"activityTapped"];
The purpose behind coercing all your objects into dictionaries is that the property list format only serializes a few classes - NSArray, NSDictionary, NSString, NSDate, NSNumber, and NSData. So we write code to represent non-supported classes using the supported ones, and vice versa, to serialize these objects in plists.
As an addendum, you mention that you need to store a record of all taps, and sort them. As I mentioned above, arrays inherently order the things they store, so that is the appropriate solution here. You'd want to build something that looked like this:
Index Item
0 <dictionary representing first tap>
1 <dictionary representing second tap>
...
n <dictionary representing n-1th tap>
In code, serializing each tap would take the same form as was described earlier, but make sure to add an extra step of calling addObject: on an NSMutableArray property with the newly-created dictionary as the parameter.

objective c when to use NSDictionary instead of NSArray [duplicate]

This question already has answers here:
What's the difference between a dictionary and an array?
(6 answers)
Closed 10 years ago.
I'm in a dilemma in terms of which of the two I should use. I will be retrieving a group of data via a restful API (returns json) and I'm not sure how I should store them before I display it on my UI View Table.
eg.
{"Events":[{"Id":5,"Name":"Event 1 2013"},{"Id":6,"Name":"Event 2 2013"}]}
I've been reading tutorials and some would use NSMutableArrays while some would use NSMutableDictionary.
How should I go about it?
BTW: I'm displaying the data on UI View table that will redirect the user to another page when tapped and if they decide to go back will have to show the previous view without reloading (uses UinavigationController)
Thanks!
EDIT:
Also, just to give you an idea on what I'm trying to do. I'm trying to follow this tutorial on splitting the data I get into section headers. On this tutorial it's using NSDictionary.
http://www.icodeblog.com/2010/12/10/implementing-uitableview-sections-from-an-nsarray-of-nsdictionary-objects/
If I use NSArray, would that affect the performance?
In NSArray - every item in the collection has an integer index, so there is an explicit order to the items. When you're retrieving/replacing/removing the stored object from the NSARRY,you need to specify the corresponding object index of that stored object.
NSDictionary - derived from the word called 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:).When you're retrieving the object from the dictionary you need to specify the key value for the objectForKey
Whenever if you're parsing the plist then NSDictionary would be ideal.You can refer apple's document here for more explanation about NSDictionary.Happy coding :)
The lookup times on NSDictionaries are faster than on NSArrays. That's one of the main advantages. Here's a link to the Apple documentation.
Generally, if you need to access data in an indexed fashion (like you need to for rows in a table) then you should use an array because you can access any specific index using indexOfObject:
Now, if you have a lot of information for each row then you should have an array of either custom objects or an array of dictionaries.
Dictionary are always faster than Arrays. Dictionary maps keys to objects, just like a hash table. It's an associative array.
For searching some value you need to iterate for arrays, in dictionary you retrieve it by key.
If you want the collection to be in some sorted order or arrival order then Array is the proper type for you.
Dictionary lacks when you end up getting two same keys.
And I feel good to use arrays for tableViews as I can directly associate row to index.

Loading NSDictionary from Plist as Listed

I'm using plist to store key-value lists. When the application needs that list, trying load list to a NSDictionary. Everything is well until here.
Here how I load the plist file:
NSString *myPlistFilePath = [[NSBundle mainBundle] pathForResource: #"cities" ofType: #"plist"];
cities = [NSDictionary dictionaryWithContentsOfFile: myPlistFilePath];
When we look at, cities is a NSDictionary. Then I pushed all list key values to a TableView, somehow its not listed as in plist file. Sorting random.
Is there way to figure out?
Thanks in advance.
An NSDictionary is not an ordered collection, that is, it does not guarantee to preserve order of the contents in any way. Its only function is to map from keys to values.
If you need the contents ordered, you can extract it from the NSDictionary using for example keysSortedByValueUsingSelector, which will extract the data in the collection, sort it by your criteria and store it in an (order preserving) NSArray.
Alternatively, consider using an Array in the root of the plist, containing an ordered list of city dictionaries. Then if you iterate over the array contained therein, they will be in the array order contained in the plist.
NSDictionary is not an ordered data structure.
Objects are listed based on allKeys functions and keys are listed in undefined way.
See the apple doc for allKeys function.
allKeys Returns a new array containing the dictionary’s keys.
(NSArray *)allKeys
Return Value A new array containing the dictionary’s keys, or an empty
array if the dictionary has no entries.
Discussion The order of the elements in the array is not defined.
If you wish to avoid using a selector to sort the keys, consider using an Array in the root of the plist. Then when you iterate over the array, the order is preserved. This runs o(n), which is shorter than the fastest possible sort algorithm by a factor of log(n)
eg:
cities{
list[
city{}
city{}
city{}
...
]
}

Resources