arrays - 修改字典中的 Swift 数组<String, AnyObject>

标签 arrays swift nsarray immutability

我有一个DictionaryAnyObject就在里面。其中之一AnyObject s 实际上是一个 Swift 数组。我正在尝试修改数组,如下所示:

class MyClass {
    internal(set) var dictionary : Dictionary<String, AnyObject>

   init() {
       self.dictionary = [
          "displayName": "Foo",  //String : String
          "elements" : []  // String : Array
       ]
   }

    // ...

   func addNumber(number : Int) {
     // Something here
   }
}

这是我对此代码的单元测试:

func testAddNumber() {

  let foo = MyClass()

  let beforeCount = foo.dictionary["elements"].count

  foo.addNumber(10)

  let afterCount = foo.dictionary["elements"].count

  XCTAssert(beforeCount + 1 == afterCount, "Count was \(afterCount)")

}

我尝试拉出数组并将其分配给临时变量,但该项目实际上并未添加到以 elements 键控的数组中.

var elements = (self.dictionary["elements"] as! [Int])
elements.append(10)

此代码运行,但是当我运行单元测试来检查是否添加了该元素时,测试失败。

如果我不使用中间赋值,则会收到有关可变性的编译器错误:

Cannot use mutating member on immutable value of type [FormGroup]

这是导致它的代码:

(self.dictionary["elements"] as! [Int]).append(10)

我尝试使用NSMutableArray而不是 Swift Array ,这可行,但我想知道是否有一个“纯粹的”Swift 解决方案。有一些帖子谈论字典的 <String, Array>类型,但这需要在中间进行强制转换,所以我认为它们不能解决我的问题。

修改数组的正确方法是什么?

最佳答案

摆脱强制展开。它要么暴露方法中的无效参数,要么暴露相关逻辑中的其他问题。

guard var elements = self.dictionary["elements"] as? [Int] else { return }
elements.append(10)

if var elements = self.dictionary["elements"] as? [Int] {
    elements.append(10)
}

我不明白如何避免在这里进行可选的展开操作,因为您试图从 [AnyObject][Int] 并且有无法知道这是否会在运行时提前起作用。

更新:

您已经添加了完整的代码,所以她是我的更新。基本上有两个主要问题。 1)你试图避免处理选项。你必须尽快对付他们。因为处理字典和数组类型的方法只返回可选值。 2)你的单元测试几乎毫无用处。除了“某些内容不为空”之外,您还应该检查许多其他内容,以确保该方法按预期工作。

这是我对您的问题的 Playground 看法。

let elementsKey = "elements"

class MyClass {
    var dictionary : Dictionary<String, AnyObject>

    init() {
        self.dictionary = [
            "displayName": "Foo",  //String : String
            elementsKey : []  // String : Array
        ]
    }

    func addNumber(number : Int) {

        guard var mutableArray = self.dictionary[elementsKey] as? [Int] else { return }

        mutableArray.append(number)
        self.dictionary[elementsKey] = mutableArray
    }
}

func testAddNumber() {

    let number: Int = 10
    let foo = MyClass()

    let before = foo.dictionary[elementsKey] as? [Int]
    foo.addNumber(number)
    let after = foo.dictionary[elementsKey] as? [Int]

   print(before != nil)
   print(after != nil)
   print(before! != after!)
   print(before?.isEmpty)
   print(after?.isEmpty)
   print(after?.contains(number))
}

testAddNumber()

关于arrays - 修改字典中的 Swift 数组<String, AnyObject>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36319761/

相关文章:

ios - 当使用 NSArray 中的字符串时,如何让 UITextField 推送到新的 ViewController?

ios - 为什么我不能将我的 NSDictionary 数据放入 UITableView

ios - 将对象添加到 NSMutableArray 将不起作用

c++ - 给定一组不同高度的堆栈,我如何选择所有可能的组合?

swift - .sks 文件中 SKSpriteNode 的子类

ios - 查找选择了哪个结构体实例

objective-c - 如何将 NSNumber 转换为 NSString

带有 async/await 的 JavaScript 数组过滤器

C指针/数组值混淆

javascript - 我可以在 Swift 代码中运行 JavaScript 吗?