Swift Array of dictionaries extension sortInPlace -
using swift 2.1 i'm trying make function sorts array of dictionaries date value key datekey.
i want add extension array type, can call using somearray.sortdictionariesbydate(datekey: string, dateformatter: nsdateformatter)
extension array element: collectiontype { mutating func sortdictionariesbydate(datekey: string, dateformatter: nsdateformatter) { sortinplace { dateformatter.dateformat = "yyyy-mm-dd't'hh:mm:ss.sssz" if let datestringa: string = ($0 as? [string: anyobject])?[datekey] as? string, let datestringb = ($1 as? [string: anyobject])?[datekey] as? string { if let datea: nsdate = dateformatter.datefromstring(datestringa), dateb: nsdate = dateformatter.datefromstring(datestringb) { return datea.compare(dateb) == .orderedascending } } return false } } }
this works fine long dictionaries typed [string: anyobject]
, if use on dictionary of type [string: string]
doesn't work since it's unable cast string
anyobject
. assume because string
struct
not class
. i've tried typecast elements [string: any]
instead, won't work regardless of using dictionaries of type [string: anyobject]
or [string: string]
.
is there cast can use support dictionaries key type string
, value type (string
, anyobject
etc.), or perhaps clause or protocol conformance can added extension avoid casting completely?
edit: here 2 example arrays per request
var samplearray1: [[string: anyobject]] = [["date": "2015-10-24t13:00:00.000z", "foo": "bar"], ["date": "2015-10-24t14:00:00.000z", "foo": "bar"]] samplearray1.sortdictionariesbydate("date", dateformatter: nsdateformatter()) var samplearray2: [[string: string]] = [["date": "2015-10-24t13:00:00.000z", "foo": "bar"], ["date": "2015-10-24t14:00:00.000z", "foo": "bar"]] samplearray2.sortdictionariesbydate("date", dateformatter: nsdateformatter())
first issue: comparing strings, not dates. fortunately, string's format make directly comparable both string , date value represents. hence, don't need convert nsdate
@ all.
the second issue typecasting dictionary<key,value1>
dictionary<key,value2>
wholesale doesn't work, when value1
covariant on value2
. may work in trivial example this...
let : [string: string] = ["name": "david", "location": "chicago"] let b = [string: anyobject]
...because compiler can see value type (string
) in a
, optimize compile time. dynamic situations yours, there's no information available ahead of time.
when need dynamism, can go old friend, objective-c:
extension array element: collectiontype { mutating func sortdictionariesbydate(datekey: string) { self.sortinplace { if let = $0 as? nsdictionary, b = $1 as? nsdictionary { return (a[datekey] as? string) < (b[datekey] as? string) } else { return false } } } } // example: var samplearray1: [[string: anyobject]] = [ ["date": "2015-10-24t13:00:00.000z", "foo": "bar"], ["date": "2015-10-24t14:00:00.000z", "foo": "bar"], ["date": "2015-10-24t10:00:00.000z", "foo": "bar"] ] var samplearray2: [[string: string]] = [ ["date": "2015-10-24t13:00:00.000z", "foo": "bar"], ["date": "2015-10-24t14:00:00.000z", "foo": "bar"], ["date": "2015-10-24t10:00:00.000z", "foo": "bar"] ] samplearray1.sortdictionariesbydate("date") samplearray2.sortdictionariesbydate("date")
note since comparing strings rather date, no nsdateformatter
needed.
Comments
Post a Comment