What is the purpose of a DictionaryIndex in Swift? - ios

Per the header documentation on Dictionary in Swift:
A hash-based mapping from Key to Value instances. Also a
collection of key-value pairs with no defined ordering.
Note in particular- no defined ordering.
With this in mind, I'm having trouble fully understanding these computed variables (and the related methods that take these types):
// The position of the first element in a non-empty dictionary.
var startIndex: DictionaryIndex<Key, Value> { get }
// The collection's "past the end" position.
var endIndex: DictionaryIndex<Key, Value> { get }
The "index" here is a DictionaryIndex.
However, the documentation on DictionaryIndex is kinda circular here:
Used to access the key-value pairs in an instance of
Dictionary<Key, Value>.
What actually is the purpose of DictionaryIndex?

We know that a Dictionary is composed of keys and values. Every key is mapped to a value based on some internal calculations. Here the mechanism used for this purpose is Hashing.
From wikipedia:
A hash table uses a hash function to compute an index into an array of buckets or slots, from which the correct value can be found.
Consider that a Dictionary is a Hash Table, which uses some hash function and returns an object of type DictionaryIndex - using which you can access particular object directly in the Dictionary.
Correct me if I am wrong!

Related

Table remove with non-integer keys

I wanted to make my removeIf(aTable, unaryPredicate) function that removes elements that satisfy the predicate.
I've written the following code on a hunch, and surprisingly for me it works:
for k, v in pairs(aTable) do
if unaryPredicate(v) then
atable[k] = nil
end
end
What is the magic behind next or pairs that allows this code to work. As far as I see it iterates exactly sizeof(aTable) times.
Lua tables are implemented essentially as hashtables. The hashtable stores an array of (key, value) pairs.
next uses a hash to quickly skip to where they key should be in the table.
However, notice that there is a nil check in the implementation of next:
if (!ttisnil(&t->array[i])) { /* a non-nil value? */
This is because when nil is assigned to a key of a table, it updates the (key, value) pair inside the hashtable, but does not actually delete that entry. Thus you're left with a (key, nil) entry in the hashtable. This design allows iteration via next to continue unaffected when existing keys are assigned values, including when assigning to nil.
However, this is an implementation detail. Whether or not there is a nil entry in the hashtable is entirely invisible in the API exposed by the table implementation. Every function externally treats these nil keys in exactly the same way as absence.
next depends only on the keys in the table. The loop removes values but not keys (in the current implementation of Lua). The documentation explicitly says that you may remove values from tables in a loop like yours. It also says that you cannot add new entries with new keys, exactly because this would confuse next.

Add parameters in tuple after initialisation in Swift

Is there any way to add parameters in tuple after initialisation?
Like :
var tupleX = ("Hi", "Rachit")
Now I want to add a parameter to tuple after which tupleX will have 3 or more parameters
Is it possible?
No. A tuple has a set number of elements. You may want to use an Array or some other class instead.
The difference between a tuple and a list (or other collections) is precisely the fixed amount of elements it contains.
From a type system perspective (1, 2) and (1, 2, 3) are of two distinct types, so of course you cannot alter the number of elements since you would be changing the type.
It's probably also important to notice that, as explained here,
Tuples are useful for temporary groups of related values. They are not suited to the creation of complex data structures. If your data structure is likely to persist beyond a temporary scope, model it as a class or structure, rather than as a tuple.
So if you need to alter a tuple overtime, you probably don't want to use a tuple, but rather a class, a struct or even a dictionary.

Why are arrays not implemented as hashes with numerical keys?

Having returned to development after an absence of over a decade I am getting myself up to speed with the latest technologies for web development. Reading this post I see that I already understood the difference between hashes and arrays.
However, doesn't this mean that arrays are just a type of hash that uses a numerical key? As there is no reason to believe that an implementation of an array will automatically maintain the sequential nature of the array indices (when you delete or insert items for example), is there any greater difference than the inherent ordering of an array?
I mean, to step through an array, you need to set up a loop through the indices, the same as looping through the keys of a hash, and then you could order the numerical hash key set to behave the same (i.e. access the items from 1 to the last number that is a key in the hash in numerical sequence). To access an array element, you use the indices of the value you want, the same as giving the numerical key from the hash.
I came to this question while learning about arrays and hashes in Ruby on Rails, but it is a general question.
A Hash is essentially an array. Hash keys have some type of conversion function to translate an object of another type (or an integer set of other values) into the integer index of an array. Conversely, an array is a Hash that does not translate the keys into a separate type or value of index. However, calling an array a Hash implies an extra layer of functionality that does not exist, since there is no key conversion.
By definition, the objects of an array are stored in consecutive locations in memory, accessible by index.
Even when either type of data structure can be used, one benefit of using hashes with Integer keys is that a larger spread of integers can be stored in a smaller number of buckets. E.g., if your number keys are 5 integers near 1, 10, 100, 1000 and 10000 you don't need 10K buckets to have a hash of these 5 elements, but you do need that many if you use a straight-up array. Hash functions tend to be recalculated and more memory reallocated as the hash grows and the benefit of using an array is that its size can be more easily controlled and can remain fixed.
Here is how declarative programming defines it.
Difference between Declarative and Procedural Programming?
http://en.wikipedia.org/wiki/Procedural_programming
http://en.wikipedia.org/wiki/Declarative_programming
There are primitive, composite, and abstract data structures.
- An Array is composite.
- A Hash is abstract.
We have both because they are fundamentally different.
For example you can't pop/push primitives into a Hash like you can with an Array, because a Hash uses unordered key-values while an Array has an index.
http://en.m.wikipedia.org/wiki/List_of_data_structures

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.

Availability of bidictionary structure?

I'm facing a case in my application where I need a bidirectional dictionary data structure, that means a kind of NSDictionary where your can retrieve a key with a value and a value with a key (all values and keys are unique).
Is there such a kind of data structure in C / ObjectiveC ?
You can do it with a NSDictionary:
allKeysForObject: Returns a new array containing the keys
corresponding to all occurrences of a given object in the dictionary.
(NSArray *)allKeysForObject:(id)anObject Parameters anObject The value to look for in the dictionary. Return Value A new array
containing the keys corresponding to all occurrences of anObject in
the dictionary. If no object matching anObject is found, returns an
empty array.
Discussion Each object in the dictionary is sent an isEqual: message
to determine if it’s equal to anObject.
And:
objectForKey: Returns the value associated with a given key.
(id)objectForKey:(id)aKey Parameters aKey The key for which to return the corresponding value. Return Value The value associated with
aKey, or nil if no value is associated with aKey.
Literally, the answer is No.
As a workaround you may create a helper class which manages two dictionaries.
Another approach is to create a thin wrapper around C++ container which implement this: boost's Bimap.
When using ARC and Objective-C objects as values or keys in C++ containers, they will handle NSObjects quite nicely. That is, they take care of memory management as you would expect - and you even get "exception safety" for free. Additionally, C++ standard containers are also a tad faster, use less memory, and provide more options to optimize (e.g. custom allocators).

Resources