Reference as key in swift dictionary
Equality can be implemented as object identity, i.e. a == b
iff a
and b
refer to the same instance of the class, and the hash value can be build from the ObjectIdentifier
(which is the same for identical objects, compare e.g. Difference between using ObjectIdentifier() and '===' Operator):
For Swift 4.2 and later:
class Test : Hashable {
static func ==(lhs: Test, rhs: Test) -> Bool {
return lhs === rhs
}
public func hash(into hasher: inout Hasher) {
hasher.combine(ObjectIdentifier(self))
}
}
For Swift 3:
class Test : Hashable {
var hashValue: Int { return ObjectIdentifier(self).hashValue }
}
func ==(lhs: Test, rhs: Test) -> Bool {
return lhs === rhs
}
For Swift 2.3 and earlier, you can use
/// Return an UnsafePointer to the storage used for `object`. There's
/// not much you can do with this other than use it to identify the
/// object
func unsafeAddressOf(object: AnyObject) -> UnsafePointer<Void>
i.e.
class Test : Hashable {
var hashValue: Int { return unsafeAddressOf(self).hashValue }
}
func ==(lhs: Test, rhs: Test) -> Bool {
return lhs === rhs
}
Example:
var dictionary = [Test: String]()
let a = Test()
let b = Test()
dictionary[a] = "A"
print(dictionary[a]) // Optional("A")
print(dictionary[b]) // nil
implement the Equatable
protocol.
Swift Reference to a Dictionary Key and Value Without Knowing Key
You should always know your dictionary keys. If you don't, you're structuring your data wrong - unknown data should always be in the value of a dictionary, never the key.
Consider instead using a dictionary with two keys: "username" and "flag".
Sample code:
var users = [[String:String]]()
users.append(["username" : "Aaron", "flag" : "yes"])
users.append(["username" : "AspiringDeveloper", "flag" : "yes"])
let userRecord = users[1]
let username = userRecord["username"]!
let flag = userRecord["flag"]!
Alternatively, you could build a basic class and avoid the dictionaries entirely:
class User {
let username: String
let flag: Bool
init(username:String, flag:Bool) {
self.username = username
self.flag = flag
}
}
var users = [User]()
users.append(User(username: "Aaron", flag: true))
users.append(User(username: "AspiringDeveloper", flag: true))
let userRecord = users[1]
let username = userRecord.username
let flag = userRecord.flag
Swift dictionary with weak reference keys?
You are describing an NSMapTable. It gives you a dictionary-like thing with weak references to its keys and/or values.
Getting reference to a Dictionary value
You can't do it in a single move except by calling a function with an inout
parameter, as you've already shown. Otherwise you cannot take a "reference" to a value type in Swift. The normal way is the old-fashioned, simple way, one step at a time: you pull out the inner dictionary, change it, and put it back again:
let key = "101"
var d = ["101": [1: "value1"]]
if var d2 = d[key] {
d2[1] = "value2"
d[key] = d2
}
It's boring but reliable.
Swift - dictionary with array - get reference to array
You can simply use a default value for the subscript and your whole code will be simplified to this:
var dic = [String: [String]]()
dic[key, default: []].append(m)
How to work with/reference keys in a dictionary with custom type in swift?
Since you want an array of names from all of the keys of your dictionary, you can do:
var pickerArray = myDictionary.keys.map { $0.name }.sorted()
myDictionary.keys
gives you all of the MyClass
instances from the keys. The .map { $0.name }
converts that array of MyClass
instances into the corresponding array of names.
And your hash
method should be:
func hash(into hasher: inout Hasher) {
hasher.combine(name)
hasher.combine(other)
}
If you look at the documentation for Hashable
, you can see a clear example of this.
how do you write a KeyPath to reference the value of a dictionary
Your question is unclear because you refer to User
in your text, but have Person
in your code. That suggests that you might have the syntax right but a hierarchy wrong.
You also may just be forgetting the question mark.
To get the type you're asking about, you also need a KidID
(the D is capitalized in Swift) value, not the KidID
type.
typealias KidID = String
enum KidName { case goatBoy }
\Person.kids["quot;] as WritableKeyPath<Person, KidName?>
Person(kids: ["quot;: .goatBoy])[keyPath: \.kids["quot;]] // .goatBoy
You don't have to supply a value in the key path, but that is a different type.
\Person.kids as WritableKeyPath<Person, [KidID: KidName]>
Person(kids: ["quot;: .goatBoy])[keyPath: \.kids]["quot;] // .goatBoy
Related Topics
What Does the '@' Symbol Mean in Swift
How to Use List Type with Codable? (Realmswift)
Select Filtered Search Results
Swift: How to Delete Part of Audio
Could Not Find an Overload for '^' That Accepts the Supplied Arguments
How to Read a File in a Swift Playground
Print() to Console Log with Color
How to Copy a Struct and Modify One of Its Properties at the Same Time
Swiftui Exporting or Sharing Files
Add Switch in Uitableview Cell in Swift
How to Implement Copy Constructor in Swift Subclass
How to Change Navigation Bar & Back Button Colour iOS 15
Swift Error Handling for Methods That Do Not Throw
Argument Labels Do Not Match Any Available Overloads
Find Nearest Smaller Number in Array
Implementing a Drag-And-Drop Zone in Swift