Reference as Key in Swift Dictionary

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



Leave a reply



Submit