Wie füge ich dem Swift Dictionary keinen Wert hinzu?

70

Ich habe in meiner App eine Anfrage an meinen Server gestellt. Und gepostete Daten wie diese. Die Serverseite wartet auf alle Parameter, auch wenn sie gleich Null sind. Aber ich konnte dem Wörterbuch keine Nullwerte hinzufügen.

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

Gibt es eine Möglichkeit, dem Wörterbuch keinen Wert hinzuzufügen?

Yatanadam
quelle
3
Wenn Sie zuweisen nilzu einem Schlüssel, es wird zurückkehren nilnächstes Mal , wenn Sie diesen Schlüssel zugreifen (weil es das Objekt und das entfernte Objekt entfernt ist nicht da). Wenn Sie einen nilWert ungleich Null darstellen möchten , können Sie verwenden NSNull().
Das paramagnetische Croissant
benutze [NSNull null] oder nichts.
Jérôme Teisseire
Dies ist nicht einmal eine schnelle Frage; Das Einfügen von NSNull-Instanzen in ein Wörterbuch zur Darstellung leerer Werte ist Teil von Foundation.
Abizern

Antworten:

114

Wie nilkann man Swift Dictionary aufwerten?

Grundsätzlich genauso, wie Sie einem Wörterbuch einen anderen Wert hinzufügen. Sie benötigen zunächst ein Wörterbuch mit einem Werttyp, der Ihren Wert enthalten kann. Der Typ AnyObjectkann keinen Wert haben nil. Ein Wörterbuch vom Typ [String : AnyObject]kann also keinen Wert haben nil.

Wenn Sie ein Wörterbuch mit einem Werttyp hatten, der ein optionaler Typ war [String : AnyObject?], kann es nilWerte enthalten. Zum Beispiel,

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

Wenn Sie die tiefgestellte Syntax verwenden möchten, um ein Element zuzuweisen, ist dies etwas schwierig. Beachten Sie, dass ein Index vom Typ Typ [K:V]hat V?. Die Option dient dazu, beim Herausgeben anzugeben, ob für diesen Schlüssel ein Eintrag vorhanden ist oder nicht, und wenn ja, den Wert. und wenn Sie es eingeben, können Sie entweder einen Wert festlegen oder den Eintrag entfernen (durch Zuweisennil ).

Das heißt, für unser Typwörterbuch [String : AnyObject?]hat der Index Typ AnyObject??. Wenn Sie einen Wert in den Index einfügen, können Sie mit der Option "Outer" optional einen Wert festlegen oder den Eintrag entfernen. Wenn wir einfach schreiben würden

x["foo"] = nil

Der Compiler schließt daraus, dass es sich nilum einen Typ handelt AnyObject??, der äußere optional, was bedeuten würde, den Eintrag für den Schlüssel zu entfernen "foo".

Um zu setzen , den Wert für die Schlüssel "foo"auf den AnyObject?Wert nil, müssen wir in einem nicht passieren niläußeren optional, eine innere optional (vom Typ enthaltend AnyObject?) von Wert nil. Um dies zu tun, können wir es tun

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

oder

x["foo"] = nil as AnyObject?

Alles, was darauf hinweist, dass wir ein nilvon AnyObject?haben und nicht AnyObject??.

newacct
quelle
Diese Lösung ist so viel schneller als NSNull()!
Franklin Yu
1
Es ist etwas einfacher zu verwenden und besser lesbar, wenn Sie dieses "Null" -Objekt als Konstante definieren:static let NullObject: AnyObject?? = Optional(nil)
Raginmari
8
Wessen gute Idee war es, einem Wörterbucheintrag nil zuzuweisen, um den Eintrag zu entfernen, selbst wenn nil ein gültiger Eintrag ist, wenn das Wörterbuch als AnyObject definiert ist? oder irgendein? Einträge? Das hat mich nur einige Stunden gekostet und meine Meinung zu Swift um ein paar Punkte gesenkt.
RenniePet
1
Die richtige Antwort ist die von Guiller. Wenn Sie mit Index einen Wert auf Null setzen, entfernen Sie den Wert und schmerzen den Schlüssel. Mit der Funktion können updateValueSie den Wert auf Null setzen, während Sie den Schlüssel behalten.
Andrea
Guter Punkt. Es ist verwirrend, aber der Punkt ist in der Tat Verwendung = nil as Foo?.
Jakub Truhlář
36

Sie können die updateValueMethode verwenden:

postDict.updateValue(nil, forKey: surname)
Guiller
quelle
1
Ich weiß nicht, warum dies abgelehnt wird, aber dies ist der beste Weg, dies imho zu tun.
Ramazan Polat
Dies ist die beste Antwort, die ich je auf SA gesehen habe. Sie sollten mit 1 Million Schlachten Wein begabt sein;) Ich habe ein Kopfgeld geschaffen und werde es Ihnen innerhalb von 24 Stunden
verleihen
@ BartłomiejSemańczyk: Dann hätten Sie wählen sollen "Eine oder mehrere der Antworten sind vorbildlich und verdienen eine zusätzliche Prämie." als Kopfgeldgrund. Jetzt sieht es so aus, als ob Sie nach einer anderen / besseren Antwort suchen.
Martin R
@MartinR Sie haben Recht, ich würde den Grund der Prämie ändern, aber ich kann nicht. Schön zu mir zu lernen;)
Bartłomiej Semańczyk
22

Wie hier dokumentiert , bedeutet das Festlegen nileines Schlüssels im Wörterbuch das Entfernen des Elements selbst.

Wenn Sie beispielsweise nullbeim Konvertieren in möchten JSON, können Sie verwendenNSNull()

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"}
Rintaro
quelle
3

Sie können den OptionalTyp verwenden

var postDict = ["pass": 123, "name": "ali", "surname": Optional()]
Priya Raj
quelle
2
postDict[surname] = Optional<AnyObject>(nil)
Vatsal Manot
quelle
In den meisten (allen?) Fällen brauchen Sie nicht einmal die <AnyObject>. Es sollte in der Lage sein, den Typ abzuleiten.
Max
2

Um nileinem Wörterbuch in Swift einen Wert hinzuzufügen , müssen die Werte Ihres Wörterbuchs vom OptionalTyp sein.

Betrachten Sie eine PersonKlasse:

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

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

Instanzen dieses PersonTyps können ein nameund ein optionales haben spouse. Erstellen Sie zwei Instanzen und fügen Sie die erste einem Wörterbuch hinzu:

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

Dieses Wörterbuch (genannt people) ordnet Namen Ehepartnern zu und ist vom Typ [String: Person?]. Sie haben jetzt ein Wörterbuch mit dem Wert Optional: Person?.

Verwenden Sie die Methode für den Typ, um den Wert des zu verwendenden Schlüssels p1.namezu aktualisieren .nilupdateValue(_: forKey:)Dictionary

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

Der Wert für den Schlüssel p1.nameist jetzt nil. Die Verwendung updateValue(_: forKey:)ist in diesem Fall etwas einfacher, da keine Wegwerfinstanz erstellt und auf gesetzt werden mussnil und diese Instanz einem Schlüssel in einem Wörterbuch zugewiesen werden muss.

NB: Siehe Rintaros Antwort zum Einfügen nullin das Wörterbuch eines Posts .

Matt Mathias
quelle
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")
    }
}
user3763801
quelle
Erste Zeile sollte sein var dict = [Int: Int?](). Es ist eine Definition, nicht nur eine Erklärung.
Franklin Yu
1

Das folgende Wörterbuch enthält einen Schlüssel mit dem Wert Null

var dict = [String:Any?]()
dict["someKey"] = nil as Any?
Hiren Panchal
quelle
1
Dies ist eine sehr richtige Antwort, um den nilWert für einen Schlüssel festzulegen.
Li Jin
-1
postDict[surname]=nil

Wenn Sie den Index verwenden, um Null zu setzen. Es löscht den Schlüssel, falls vorhanden. In diesem Fall wird der Schlüsselname aus dem Wörterbuch entfernt, falls vorhanden.

Um den Wert auf Null zu setzen, gibt es bestimmte Möglichkeiten.

postDict.updateValue(nil, forKey: surname)

oder

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

oder

postDict[surname] = nil as AnyObject?
vntstudy
quelle