如何在Swift字典中添加nil值?


70

我已经在我的应用中向服务器提出了请求。然后像这样发布数据。服务器端正在等待所有参数,即使它们为零。但是我无法将nil值添加到字典中。

 var postDict = Dictionary<String,AnyObject>
 postDict[pass]=123
 postDict[name]="ali"
 postDict[surname]=nil // dictionary still has only pass and name variables.

有没有一种方法可以将nil值添加到字典中?


3
分配nil给键后,下次访问该键时它将返回nil(因为它会删除对象,而删除的对象不存在)。如果要表示一个非nilnull值,则可以使用NSNull()
顺磁牛角包

使用[NSNull null]或不使用任何内容。
杰罗姆Teisseire

这甚至不是一个快速的问题。将NSNull实例放入字典中以表示空值是Foundation的一部分。
阿比森2014年

Answers:


114

如何为nilSwift字典增加价值?

基本上与您将其他任何值添加到字典的方式相同。您首先需要一个字典,该字典的值类型可以保存您的值。类型AnyObject不能有值nil。所以类型的字典[String : AnyObject]不能有值nil

如果您有一个字典,其值类型是可选类型,例如[String : AnyObject?],则它可以保存nil值。例如,

let x : [String : AnyObject?] = ["foo" : nil]

如果要使用下标语法来分配元素,则有些棘手。请注意,type的下标[K:V]具有type V?。可选的是,当您获得它时,它指示是否有该键的条目,如果有,则指示值;并将其放入后,您可以设置一个值或删除该条目(通过分配nil)。

这意味着对于我们的type字典[String : AnyObject?],下标具有type AnyObject??。同样,当您在下标中输入值时,“外部”可选选项允许您设置值或删除条目。如果我们简单地写

x["foo"] = nil

编译器推断该nil类型AnyObject??为外部可选类型,这意味着删除key的条目"foo"

为了将key的值设置为value ,我们需要传入一个非外部的option,其中包含一个value的内部的(类型)。为了做到这一点,我们可以做"foo"AnyObject?nilnilAnyObject?nil

let v : AnyObject? = nil
x["foo"] = v

要么

x["foo"] = nil as AnyObject?

表示我们有一个nilof的任何东西AnyObject?,而没有AnyObject??


这个解决方案比NSNull()
富兰克林·于

1
如果将此“ Null”对象定义为常量,则使用起来会更容易一点并且更具可读性:static let NullObject: AnyObject?? = Optional(nil)
Raginmari

8
是谁的一个聪明的主意,即使在字典被定义为具有AnyObject的情况下,即使nil是有效条目,将nil分配给字典条目也意味着删除该条目?或任何?参赛作品?那只花了我几个小时,并降低了我对Swift的看法。
RenniePet

1
正确的答案是来自Guiller的答案,可以通过使用下标设置nil的值来删除键上的值,而使用该功能时updateValue,可以在保持键的同时将值设置为nil。
安德里亚(Andrea)

好点子。令人困惑,但是重点确实是use = nil as Foo?
雅各布·特鲁拉斯(JakubTruhlář)

36

您可以使用以下updateValue方法:

postDict.updateValue(nil, forKey: surname)

1
不知道为什么这会被否决,但这是做这件事的最好方法。
Ramazan Polat

这是我在SA上见过的最好的答案。您应该拥有一百万次葡萄酒大战的天赋;)我创造了一个赏金,我将在24小时内将其奖励给您;)
BartłomiejSemańczyk17年

@BartłomiejSemańczyk:然后,您应该选择“一个或多个答案是模范的,值得额外赏金。” 作为赏金理由。现在看起来好像您在寻找另一个/更好的答案。
Martin R

@MartinR你是对的,我会更改赏金的原因,但我不能。很好地向我学习;)
BartłomiejSemańczyk17年

22

如此处所述nil在字典中设置键意味着删除元素本身。

例如,如果要null转换JSON为,可以使用NSNull()

var postDict = Dictionary<String,AnyObject>()
postDict["pass"]=123
postDict["name"]="ali"
postDict["surname"]=NSNull()

let jsonData = NSJSONSerialization.dataWithJSONObject(postDict, options: NSJSONWritingOptions.allZeros, error: nil)!
let jsonString = NSString(data: jsonData, encoding: NSUTF8StringEncoding)!
// -> {"pass":123,"surname":null,"name":"ali"}


2
postDict[surname] = Optional<AnyObject>(nil)

在大多数(全部?)情况下,您甚至不需要<AnyObject>。它应该能够推断出类型。
最多

2

nil在Swift中为字典添加值,则字典的值必须为Optional类型。

考虑一个Person类:

class Person {
    let name: String
    weak var spouse: Person?

    init(name: String, spouse: Person?) {
        self.name = name
        self.spouse = spouse
    }
}

Person类型的实例可以具有name和可选spouse。创建两个实例,然后将第一个实例添加到字典中:

let p1 = Person(name: "John", spouse: nil)
let p2 = Person(name: "Doe", spouse: p1)
p1.spouse = p2
var people = [p1.name: p1.spouse]

该词典(称为people)将姓名映射到配偶,并且类型为[String: Person?]。现在,您有了一个字典,其值Optional类型为:Person?

要将键的值更新p1.namenil,请使用类型updateValue(_: forKey:)上的方法Dictionary

people.updateValue(nil, forKey: p1.name)
people[p1.name] 

密钥的值p1.name现在为nilupdateValue(_: forKey:)在这种情况下,使用起来更简单一些,因为它不需要创建一个一次性实例,将其设置为nil,并将该实例分配给字典中的一个键。

注意:有关插入null帖子字典的信息,请参见林太郎的答案。


2
var dict = [Int:Int?]()

dict[0] = (Int?).none // <--- sets to value nil

dict[0] = nil         // <-- removes

dict[0] = .none       // <-- same as previous, but more expressive

switch dict[0] {
case .none:
    Swift.print("Value does not exist")

case .some(let value):
    if let value = value {
        Swift.print("Value exists and is", value)
    } else {
        Swift.print("Value exists and is nil")
    }
}

第一行应该是var dict = [Int: Int?]()。这是一个定义,而不仅仅是声明。
富兰克林·于


-1
postDict[surname]=nil

使用下标设置nil时。如果存在,它将删除密钥。在这种情况下,密钥姓氏将从字典中删除(如果存在)。

要将值设置为nil,有某些方法。

postDict.updateValue(nil, forKey: surname)

要么

let anyObjectNil : AnyObject? = nil
postDict[surname] = anyObjectNil

要么

postDict[surname] = nil as AnyObject?
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.