Get position as int from Set<>.index in Swift - swift

I have a set collection and I want to get index of an element. I'm using firstIndex function of set but It returns Set.index. How can I convert it to int?
let index = mySet.firstIndex(of: dataSource) // This returns Set<>.index
Set.index Documentation

Set is unordered, try using an Array for example

It is very easy to convert a set index to an int
index.hashValue
however you will find that that index isn't very useful
Set(["a", "b", "c"]).firstIndex(of: "a")?.hashValue
// 5346078814578125500
this is because a set uses a hash table as its underlying storage mechanism. You'll see this if you try to print the index itself
Index(_variant: Swift.Set<Swift.String>.Index._Variant.native(Swift._HashTable.Index(bucket: Swift._HashTable.Bucket(offset: 3), age: -233657665)))
What firstIndex returns to you is simply the hashkey at which that element is stored. It does not relate to any kind of "position" because hash tables don't have a meaningful sense of position.

Related

suffix array Index out of bounds

I have an array , when I suffix array and want to select element , I get error: Index out of bounds.
But when I prefix array and select element, It's sucess.
How should I do that I can select after suffix array?
Here is code:
let array = [1,2,3,4,5,6,7,8,9,10]
let suffixArray = array.suffix(5)//[6,7,8,9,10]
let prefixArray = array.prefix(5)//[1,2,3,4,5]
print(suffixArray[2])//Index out of bounds
print(prefixArray[2])//sucess print "3"
The problem you are having is that with .suffix the array does not start with 0. So if you wanted to print the 3rd number in the suffix array, you would have to call print(suffixArray[7].
If you read the description for the return value here. It reads:
A subsequence terminating at the end of the collection with at most maxLength elements.
And if you read the description to subsequence:
A collection representing a contiguous subrange of this collection’s elements. The subsequence shares indices with the original collection.
Full example for playground:
let array = [1,2,3,4,5,6,7,8,9,10]
let suffixArray = array.suffix(5) // [6,7,8,9,10]
let prefixArray = array.prefix(5) // [1,2,3,4,5]
var newSuffixArray: [Int] = []
for i in suffixArray {
newSuffixArray.append(i)
}
print(suffixArray[7]) // 8
print(newSuffixArray[2]) // 8
print(prefixArray[2]) // 3
Both prefix and suffix return an ArraySlice rather than another Array.
Here's an excerpt from the ArraySlice documentation:
Unlike Array and ContiguousArray, the starting index for an
ArraySlice instance isn’t always zero. Slices maintain the same
indices of the larger array for the same elements, so the starting
index of a slice depends on how it was created, letting you perform
index-based operations on either a full array or a slice. Sharing
indices between collections and their subsequences is an important
part of the design of Swift’s collection algorithms.
You can see that by looking into the indices property of prefixArray and suffixArray.
Generally you are encouraged to use methods of accessing elements that collections provide instead of assuming values of indices.

How can I sort dictionary by an array guide when I have order keys?

How can I sort a dictionary by key if I have a second array guide where I had all sorted key of dictionary?
Example:
let dict = ["35": "a", "398":"b", "98":"c"]
let guideArray = ["398","35","98"]
so I want a sorted dict like:
let sortDict = ["398": "b", "35":"a", "98":"c"]
A dictionary is not a sorted type of table by definition so cannot be sorted and nothing ensures that the order of the elements won't change. I don't think is the best approach.
You could make an array and add the elements there if what matters for you is the order.

Swift: Get max value for key in array of dictionaries

I have an array containing dictionaries.
let arr = [["test":1], ["test":2], ["test":3], ["test":4]]
I now need to get the one dictionary that contains the highest value for the key "test" (without iterating through everything). I was thinking about filter(_:) but this will only filter out. map(_:) also does not work as I need to filter and not to map.
There's an example how to get the key with the highest value in a dictionary but this does not work in this case.
let hues = ["Heliotrope": 296, "Coral": 16, "Aquamarine": 156]
let greatestHue = hues.max { a, b in a.value < b.value }
print(greatestHue)
Any help is appreciated!
You can use max much like in your example.
let arr = [["test":1], ["test":4], ["test":3], ["test":2]]
print(arr.max { $0["test"]! < $1["test"]! })
This gives the dictionary with the highest value.
Of course the use of ! is bad unless it is guaranteed that each dictionary really has a "text" key.
Also note that using max will still result in the entire array being iterated. You can't avoid that unless your dictionaries are always sorted by the value. Then in that case simply use last instead of max.

How do I search a hash table?

I've just started learning about hash tables and I understand how to insert but not how to search. These are the algorithms I'll be basing this question off:
Hashing the key
int Hash (int key) {
return key % 10; //table has a max size of 10
}
Linear probing for collision resolution.
Suppose I call insert twice with the keys 1, 11, and 21. This would return slot 1 for all 3 keys. After collision resolution the table would have the values 1, 11, and 21 at slots 1, 2, and 3. This is what I assume would happen with my understanding of inserting.
After doing this, how would I get the slots 2 and 3 if I search for the keys 11 and 21? From what I've read searching a hash table should do literally the same thing as inserting except when you arrive at the desired slot, you return the value at that slot instead of inserting something into it.
If I take this literally and apply the same algorithm, if I search for the key 11 I would arrive at slot 4 because it would start at slot 1 and keep probing forward until it finds an empty slot. It wouldn't stop at slot 2 even though it's what I want because it's not empty.
I'm struggling with this even if I use separate chaining. All 3 keys would be stored at slot 1 but using the same algorithm to search would return slot 1, not which node in the linked list.
Each slot stores a key/value pair. As you're searching through each slot, check whether the key is equal to the key you're searching for. Stop searching and return the value when you find an equal key.
With separate chaining, you can do a linear search through the list, checking the key against each key in the list.
I usually prefer to make each entry in the table a struct so I can create a linked list to handle collisions. This reduces collisions significantly. Something like this.
struct hashtable
{
int key;
struct hashtable *pList;
};
struct hashtable ht[10];
void Insert(int key);
{
index = Hash(key);
if (!ht[index].key)
{
ht[index].key = key;
ht[idnex].pList = 0;
}
else
{
struct hashtable *pht;
pht = ht[index].pList;
while (pht->pList)
pht = pht->pList;
pht->pList = new struct hashtable;
pht->pList->key = key;
pht->pList->pList = 0;
}
return;
}
The lookup function would, of course, have to traverse the list if it doesn't find the first entry's key matches. If performance is critical, you could use other strategies for the linked lists such as sorting them and using a binary search.

read int dynamically in array

I have values i wanted to load dynamically in an array, here are the examples
First of all i define 3 different values in my init, and then in my array i want it to determine which value to read. Example:
First i define the value
int value1=20
int value2=40;
int value3=60;
i then define another int in my array called valueToLoad, and i'll give each of them a number tag. and i want the individual array item to read different value based on their number tag so that Item 1 will read value1, Item 2 will read value2 and so on. i tried the method below to convert NSString into int:
NSString *valueVariable=[NSString stringWithFormat:#"value%d",i]; (i being the number tag)
int valueToRead = [valueVariable intValue];
unfortunately, this conversion doesn't supports conversion of any other thing except if the string is actual integer.
However i do not want to run the IF statement to do:
if(tag==1)
{ int valueToLoad= value1;}
For who don't understand. I am just trying to read different Int value in an array based on the number of array. Let's assume i have 3 Items in array naming A,B,and C. i want Item A to read Value 1, ItemB to read Value2 and so on.
Why don't you simply do something like
int values[] = {20,40,60};
...
int valueToRead = values[i]; //or i-1, depending if i starts from 0 or 1
?
Not sure about the context of your problem but why don't you use an NSDictionary?
That way you can store your number tag as the key and your value to read as the value...
You fill your dictionary like this:
NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:value1, tag1, value2, tag2, nil];
Read your value using : [dict objectForKey:tag1];
You can use an array, store your variables in there, and index into it.
You can use a dictionary, store your variables as values, and look them up by key.
You can declare all your variables as #property, and then use [self valueForKey:] to look them up by name.
You can build the name of the ivar as a string, and then use something like object_getInstanceVariable() to retrieve it's value directly (this is similar to #3, except you don't have to declare it as an #property).
If you're dealing with views, you can assign each view a unique tag and then retrieve it via [superview viewWithTag:aTag].
EDIT: Note that this only works with instance variables. This does not work with global/static variables.
took from: Objective C Equivalent of PHP's "Variable Variables"