Extension of Dictionary Where <String, Anyobject>

extension of Dictionary where String, AnyObject

>=3.1

From 3.1, we can do concrete extensions, ie:

extension Dictionary where Key == String {}

<3.1

We can not conform concrete types w/ concrete generics, ie:

extension Dictionary where Key == String

However, because Dictionary conforms to sequence and we can conform protocol types w/ concrete generics, we could do:

extension Sequence where Iterator.Element == (key: String, value: AnyObject) {
func doStuff() {...

Otherwise, we can constrain our key to a protocol that string conforms to like this:

extension Dictionary where Key: StringLiteralConvertible, Value: AnyObject {
var jsonString: String {
return ""
}
}

As per your updated answer. Json serialization needs an object, Swift Dictionaries are structs. You need to convert to an NSDictionary You must specify Key to conform to NSObject to properly convert to an NSDictionary.

Small note: Dictionaries already type constrain Key to be Hashable, so your original constraint wasn't adding anything.

extension Dictionary where Key: NSObject, Value:AnyObject {

var jsonString:String {

do {
let stringData = try NSJSONSerialization.dataWithJSONObject(self as NSDictionary, options: NSJSONWritingOptions.PrettyPrinted)
if let string = String(data: stringData, encoding: NSUTF8StringEncoding){
return string
}
}catch _ {

}
return ""
}
}

Note, that the dictionaries must conform to this type to access the extension.

let dict = ["k" : "v"]

Will become type [String : String], so you must be explicit in declaring:

let dict: [NSObject : AnyObject] = ["k" : "v"]

Extending Optional Dictionary String, AnyObject

use dot syntax to access the Key and Value of Wrapped.

extension Optional where Wrapped: DictionaryLiteralConvertible, Wrapped.Key: StringLiteralConvertible, Wrapped.Value: AnyObject {
func doSomething() {
print("did it")
}
}

now you can call this:
Optional(["asdf":123]).doSomething()

but not this:
Optional([123:123]).doSomething()

How to write Dictionary extension that handles optional values

You could do this with reflection. Doesn't require much more code than you already have:

extension Dictionary
{
func someMethod()
{
for (key, value) in self
{
var valueRef = _reflect(value)

while valueRef.disposition == .Optional && valueRef.count > 0 && valueRef[0].0 == "Some"
{
valueRef = valueRef[0].1
}

if let valueString: String = valueRef.value as? String
{
print(" \(key) = \(valueString)")
}
else
{
print(" \(key) = \(value) cannot be cast to `String`")
}
}
}
}

let dictionary: [String : AnyObject?] = ["foo" : "bar"]
dictionary.someMethod()

Returns

foo = bar

let dictionary: [String : AnyObject?] = ["foo" : nil]
dictionary.someMethod()

Returns

foo = nil cannot be cast to `String`

let dictionary: [String : AnyObject?] = ["foo" : UIViewController()]
dictionary.someMethod()

Returns

foo = Optional(<UIViewController: 0x7fee7e819870>) cannot be cast to `String`

Dictionary extension in Swift is not recognized

There is no need to constrain Dictionary Value type at all:

extension Dictionary where Key: ExpressibleByStringLiteral {
var jsonString: String? {
guard let data = try? JSONSerialization.data(withJSONObject: self)
else { return nil }
return String(data: data, encoding: .utf8)
}
}

How to create Dictionary extension

You're almost done, just make right constraint on the Key type:

extension Dictionary where Key == String {
func getInAmountFormat(str: String) -> String? {
if let value = self[str] as? Double {
return String(format: "%.2f", value)
}
return nil
}
}

Also, here is an useful answer.

How to remove dictionary[String:AnyObject] for array using filter function in swift?

Try using this

    var globalCountArray = [AnyObject]()
var assetDictionary = [String:AnyObject]()
globalCountArray.append(assetDictionary as AnyObject)
let dict = [String:AnyObject]()




globalCountArray = globalCountArray.filter({ (obj) -> Bool in

if obj is[String:AnyObject] {

return (obj as! [String:AnyObject]) != dict


}
return false
})

--------- OR You can achieve the same via ----------

globalCountArray = globalCountArray.filter({ (obj) -> Bool in

if obj is[String:AnyObject] {

return (obj as! [String:AnyObject]) == dict


}
return true
})

You need to add this method to outside your class definition.

public func !=(lhs: [String: AnyObject], rhs: [String: AnyObject] ) -> Bool {
return !NSDictionary(dictionary: lhs).isEqual(to: rhs)
}

public func ==(lhs: [String: AnyObject], rhs: [String: AnyObject] ) -> Bool {
return NSDictionary(dictionary: lhs).isEqual(to: rhs)
}

Swift: Constrained extension on Dictionary by Element

Element is a tuple:

typealias Element = (Key, Value)

That cannot match the type you're trying to compare it to (a Dictionary). You can't even say something like where Element:(String, AnyObject) because tuples don't subtype that way. For example, consider:

var x: (CustomStringConvertible, CustomStringConvertible) = (1,1)
var y: (Int, Int) = (1,1)
x = y // Cannot express tuple conversion '(Int, Int)' to ('CustomStringConvertible', 'CustomStringConvertible')

Compare:

var x1:CustomStringConvertible = 1
var y1:Int = 1
x1 = y1 // No problem

I suspect you get "undeclared type" is because Element is no longer an unbound type parameter, it's a bound type parameter. Dictionary is conforming to SequenceType here. So you can't parameterize on it (at least not in one step; you have to chase it through another layer of type parameters to discover it's "ultimately" unbound). That seems a bad error message, but I suspect it bubbles out of "undeclared type out of the list of types that could possibly be used here." I think that's worth opening a radar on for a better error message.

Instead, I think you mean this:

extension Dictionary where Key: String, Value: AnyObject { }

EDIT for Swift 2:

This is no longer legal Swift. You can only constrain based on protocols. The equivalent code would be:

protocol JSONKey {
func toString() -> String
}
extension String: JSONKey {
func toString() -> String { return self }
}

extension Dictionary where Key: JSONKey, Value: AnyObject { ... }

Dictionary extension to convert nil values to NSNull

You can't add nil to a dict. So you have to force it in there with a cast to someType? just so you have a key.

Borrowing from this Q/A for the OptionalConvertible solution:

protocol OptionalConvertible {
typealias WrappedValueType = AnyObject
func toOptional() -> WrappedValueType?
}

extension Optional: OptionalConvertible {
typealias WrappedValueType = Wrapped

// just to cast `Optional<Wrapped>` to `Wrapped?`
func toOptional() -> WrappedValueType? {
return self
}
}

extension Dictionary where Value: OptionalConvertible, Key: NSCopying {
//dict: Dictionary<Key, Optional<Value>>
func convertToNSDictionary() -> NSDictionary {

let mutableDict : NSMutableDictionary = NSMutableDictionary()

for key in self.keys {
if let maybeValue = self[key] {
if let value = maybeValue.toOptional() {
mutableDict[key] = value as? AnyObject
} else {
mutableDict[key] = NSNull()
}
}
}
return mutableDict

}
}

var optionalObject : UIView? = nil

var dict : [NSString:AnyObject?] = [:]
dict["alpha"] = 1
dict["beta"] = 2
dict["delta"] = optionalObject as AnyObject? // force a nil into the dict

dict // ["beta": {Some 2}, "alpha": {Some 1}, "delta": nil]

let nsdict = dict.convertToNSDictionary() // ["alpha": 1, "beta": 2, "delta": {NSObject}]

Or a more practical approach :

extension NSDictionary {

static func fromDictionary<Key: Hashable, Value:AnyObject where Key: NSCopying>(dictionary:Dictionary<Key, Value>) -> NSDictionary {

let mutableDict : NSMutableDictionary = NSMutableDictionary()

for key in dictionary.keys {
if let value = dictionary[key] {
mutableDict[key] = value
} else {
mutableDict[key] = NSNull()
}
}
return mutableDict
}

static func fromDictionary<Key: Hashable, Value:AnyObject where Key: NSCopying>(dict: Dictionary<Key, Optional<Value>>) -> NSDictionary {

let mutableDict : NSMutableDictionary = NSMutableDictionary()

for key in dict.keys {
if let maybeValue = dict[key] {
if let value = maybeValue {
mutableDict[key] = value
} else {
mutableDict[key] = NSNull()
}
}
}
return mutableDict
}
}


Related Topics



Leave a reply



Submit