Swift 使语句更清晰:在字典中检查对象的键

Swift 使语句更清晰:在字典中检查对象的键,swift,Swift,我有一本类型为-[String:[MyClass]]的字典 我有一个类型为MyClass的数组,我要检查的是,我的字典是否包含特定键的MyClass对象数组。若有,则将元素附加到数组中,若并没有,则使用单个元素创建新数组MyClass。我的结局是: for item in items{ if let _ = dict[key] { // Add operations if corresponding array exist dict[key]?.appen

我有一本类型为-
[String:[MyClass]]
的字典

我有一个类型为
MyClass
的数组,我要检查的是,我的字典是否包含特定键的
MyClass
对象数组。若有,则将元素附加到数组中,若并没有,则使用单个元素创建新数组
MyClass
。我的结局是:

for item in items{
    if let _ = dict[key] {
        // Add operations if corresponding array exist
        dict[key]?.append(item)         
    } else {
        // Create array if need
        dict[key] = [item]
   }
}
它可以工作,但看起来有点难看,我使用可选绑定检查数组是否存在,但不使用结果(通配符模式)

有没有办法让代码看起来更短更干净?谢谢。

首先,您可以使用可选绑定测试并获取现有值, 然后附加(或设置)所有新项目:

if let oldItems = dict[key] {
    dict[key] = oldItems + items
} else {
    dict[key] = items
}
这可以通过零合并运算符来简化:

dict[key] = (dict[key] ?? []) + items
Swift 4中,您只需使用:

独立示例:

var dict = ["foo": [1, 2, 3]]

dict["foo", default: []] += [4, 5]
dict["bar", default: []] += [6,7]

print(dict) // ["bar": [6, 7], "foo": [1, 2, 3, 4, 5]]
首先,您可以使用可选绑定测试并获取现有值, 然后附加(或设置)所有新项目:

if let oldItems = dict[key] {
    dict[key] = oldItems + items
} else {
    dict[key] = items
}
这可以通过零合并运算符来简化:

dict[key] = (dict[key] ?? []) + items
Swift 4中,您只需使用:

独立示例:

var dict = ["foo": [1, 2, 3]]

dict["foo", default: []] += [4, 5]
dict["bar", default: []] += [6,7]

print(dict) // ["bar": [6, 7], "foo": [1, 2, 3, 4, 5]]

可以使用以下实现来避免通配符模式:

import Foundation

class MyClass { }
class Apple : MyClass { }
class Ant : MyClass { }
class Ambulance : MyClass { }

class Test {

 var dictionary : [String : [MyClass.Type]] = [:]
 let items : [MyClass.Type] = [Apple.self, Ant.self, Ambulance.self]
 let key = "a"

 public func insert(key : String, items : [MyClass.Type] ) {
    guard !items.isEmpty else { return }

    items.forEach { (item) in
        if dictionary[key] == nil {
            dictionary[key] = [item]
        } else {
            dictionary[key]?.append(item)
        }
    }
 }

}

let test = Test()
test.insert(key: test.key, items: test.items)
print(test.dictionary)
输出:
可以使用以下实现来避免通配符模式:

import Foundation

class MyClass { }
class Apple : MyClass { }
class Ant : MyClass { }
class Ambulance : MyClass { }

class Test {

 var dictionary : [String : [MyClass.Type]] = [:]
 let items : [MyClass.Type] = [Apple.self, Ant.self, Ambulance.self]
 let key = "a"

 public func insert(key : String, items : [MyClass.Type] ) {
    guard !items.isEmpty else { return }

    items.forEach { (item) in
        if dictionary[key] == nil {
            dictionary[key] = [item]
        } else {
            dictionary[key]?.append(item)
        }
    }
 }

}

let test = Test()
test.insert(key: test.key, items: test.items)
print(test.dictionary)
输出:
为什么要在循环中执行此操作?@RamyAlZuhouri,因为我需要在[MyClass]项集合的迭代过程中修改集合。为什么要在循环中执行此操作?@RamyAlZuhouri,因为我需要在[MyClass]项集合的迭代过程中修改集合。谢谢!Code-dict[“bar”,默认值:[]+=[6,7]是dictionary dict中键“bar”的平均值检查值,如果不存在,是否创建空数组?我理解正确吗?@EvgeniyKleban:首先,下标getter返回值(如果存在)或空数组。然后添加新项目。最后,下标设置器在字典中设置新值。我在代码中尝试了您的解决方案,但它说-myClass不符合协议序列。我以:groupedOperationsDict[shiftName,默认值:[]]结束。append(item)@EvgeniyKleban:我的意思是,您可以通过
append(contentsOf:items)
一步将整个数组追加—无需for循环。或者使用
附加(项目)
附加单个项目。谢谢!Code-dict[“bar”,默认值:[]+=[6,7]是dictionary dict中键“bar”的平均值检查值,如果不存在,是否创建空数组?我理解正确吗?@EvgeniyKleban:首先,下标getter返回值(如果存在)或空数组。然后添加新项目。最后,下标设置器在字典中设置新值。我在代码中尝试了您的解决方案,但它说-myClass不符合协议序列。我以:groupedOperationsDict[shiftName,默认值:[]]结束。append(item)@EvgeniyKleban:我的意思是,您可以通过
append(contentsOf:items)
一步将整个数组追加—无需for循环。或者使用
附加(项目)
附加单个项目。