Shortcut to modify a hash

2019-06-26 06:32发布

问题:

I wonder if the following can be written shorter

var t = [String:[Int]]()
if t["a"] == nil { t["a"] = [1] }
else { t["a"]!.append(2) }

That is assigning a hash value if it does not exist and re-use it else.

I know I can write a function like

func extend(inout t:[String:[Int]], key:String, n:Int) {
  if t[key] == nil { t[key] = [n] }
  else { t[key]!.append(n) }
}

but wonder if there is a more elegant way.

Edit Actually I was looking for a shortcut for the function but copy/pasted test code above having different init/add values.

回答1:

If you are trying to append 1 if the array exists, and create [1] if the array doesn't exist (as implied by your extend function), you can use the nil coalescing operator ?? like so:

t["a"] = (t["a"] ?? []) + [1]

Extended example:

var t = [String:[Int]]()

t["a"] = (t["a"] ?? []) + [1]    // t = ["a":[1]]
t["a"] = (t["a"] ?? []) + [2]    // t = ["a":[1,2]]
t["b"] = (t["b"] ?? []) + [4]    // t = ["b":[4], "a":[1,2]]


回答2:

You can use the fact that optional chaining returns nil if the method could not be called:

if (t["a"]?.append(2)) == nil {
    t["a"] = [1]
}

Implementation as a generic function (which operates on the optional dictionary value, not on the entire dictionary):

var t = [String:[Int]]()

func setOrAppend<T>(inout array : [T]?, initialValue : T, newValue : T) {
    if (array?.append(newValue)) == nil {
        array = [initialValue]
    }
}

println(t)                  // [:]
setOrAppend(&t["a"], 1, 2)
println(t)                  // [a: [1]]
setOrAppend(&t["a"], 1, 2)
println(t)                  // [a: [1, 2]]


标签: swift hash