Custom sequence for Swift Dictionary
If I'm understanding correctly, how about just forwarding on the generate?
func generate() -> DictionaryGenerator<String, STCQuestion> {
return questionDict.generate()
}
(You don't need to implement GeneratorType
, just SequenceType
should do. It's generate()
itself that returns a GeneratorType
, and that's what has to implement next()
, which the existing generate()
implementation in Dictionary already does for you.)
Full worked example based on your code:
// Playground - noun: a place where people can play
import Foundation
class STCQuestion {
let foo: String
init(_ foo: String) {
self.foo = foo
}
}
class STCQuestionList : SequenceType {
private var questionDict: [String : STCQuestion] = [ : ];
subscript(key : String?) -> STCQuestion? {
get {
if key != nil {
return self.questionDict[key!];
}
return nil;
}
set(newValue) {
if key != nil {
self.questionDict[key!] = newValue;
}
}
}
func generate() -> DictionaryGenerator<String, STCQuestion> {
return questionDict.generate()
}
}
var list = STCQuestionList()
list["test"] = STCQuestion("blah")
list["another"] = STCQuestion("wibble")
list["third"] = STCQuestion("doodah")
for (key, value) in list {
println("Key: \(key) Foo: \(value.foo)")
}
// Output:
// Key: test Foo: blah
// Key: another Foo: wibble
// Key: third Foo: doodah
Write a Generator to custom dictionary class in Swift with Generics
Got the answer,
you will have to add following code extending orderedDictionary with SequenceType and adding a Generate method
/// extension class
extension OrderedDictionary: SequenceType {
/// Creates a generator for each (key, value)
func generate() -> GeneratorOf<(Tk , Tv)> {
var index = 0
return GeneratorOf<(Tk , Tv)> {
if index < self.count {
let key = self.keys[index]
let value = self[index]
index++
return (key, value!)
} else {
index = 0
return nil
}
}
}
}
How to maintain the order of the data in Dictionary in Swift?
Short answer:
You can not maintain order in the Dictionary
.
Long answer:
Apple says:
Dictionaries are unordered collections of key-value associations.
Please refer this
To maintain the order you need to use the Array
or create sorted
Array
(Ascending, Descending or by using specific key) from the Dictionary
and use it.
Thank you.
Sequence extension that works on Arrays, Sets and Dictionaries in Swift
As isMultiple(of:)
belongs to all integer types a generic version must be constrained to BinaryInteger
extension Sequence where Element : BinaryInteger {
var isAllEven : Bool {
allSatisfy {$0.isMultiple(of: 2)}
}
}
But this cannot cover Dictionary
, because although Dictionary
conforms to Sequence
the Element
type is different.
You could write a second extension of Sequence
which matches the Dictionary
tuple type
extension Sequence where Element == (key:String, value:Int) {
var isAllEven : Bool {
allSatisfy {$0.value.isMultiple(of:2)}
}
}
but this considers only String
keys and Int
values
A more generic way is to extend Dictionary
directly
extension Dictionary where Value : BinaryInteger {
var isAllEven : Bool {
allSatisfy {$0.value.isMultiple(of: 2)}
}
}
Swift: Sort dictionary by keys with custom order
It seems to me your main challenge is a way to sort your season strings. The fact that you want to sort an array of dictionary keys is incidental.
I would suggest creating a global function valueForSeason that takes a string as input. It would return a double representing the season: The starting year value as the integer part, plus 0.0 for summer and 0.5 for winter. Return 0.0 for a malformed season string so those float to the top.
Then you could pull out your dictionary keys into an array and sort them by valueForSeason:
var keys = dict.keys
keys.sort()
{
$0.valueForSeason() < $1.valueForSeason()
}
Note that you've got a Y2K bug lurking in your data format that you really can't fix. You're using 2 character years, and 99 most likely represents 1999, but it would sort after 14. You can play games like assuming dates after '50 are in the 1900's and dates before '50 are in the 2000's, but that approach is error-prone. You'd be much better off changing your string format to " YYYY" (e.g. "Summer 2014" and "Winter 2014/2015")
Preserve order of dictionary items as declared in Swift?
In your case an array of custom objects might be more appropriate.
Here is a simple example that should help to get you started:
struct Unit : Printable {
let name: String
let factor: Double
// println() should print just the unit name:
var description: String { return name }
}
let units = [
Unit(name: "kg", factor: 1000.0),
Unit(name: "g", factor: 1.0),
Unit(name: "mg", factor: 0.001),
Unit(name: "lb", factor: 453.592292),
Unit(name: "oz", factor: 28.349523)
]
println(units) // [kg, g, mg, lb, oz]
(I am not sure if the non-metric unit factors are correct :)
How do I expose a Swift Dictionary as a typed sequence of key-value pairs?
Probably someone comes up with a more elegant solution, but this works:
class Foo<K : Hashable, V> {
var dict: [K:V] = [:]
func asSequence() -> SequenceOf<(K, V)> {
return SequenceOf(dict)
}
}
... I could probably figure out how to wrap dict in something that conforms to SequenceType ...
That is exactly what SequenceOf<>
does for you. From its API
documentation:
/// A type-erased sequence.
///
/// Forwards operations to an arbitrary underlying sequence with the
/// same `Element` type, hiding the specifics of the underlying
/// sequence type.
Create a Swift Dictionary subclass?
Swift dictionaries are structs, not classes, so they cannot be subclassed. Ideally, the methods you're working with would be declared to take an appropriately constrained generic CollectionType (or ExtensibleCollectionType, or SequenceType, depending on the situation), rather than specifically a Dictionary.
If that doesn't work for you for whatever reason, you could subclass NSDictionary instead.
(edit) and as Antonio points out, you can do extension Dictionary { … } to add things to the Dictionary struct, which can replace subclassing in some cases.
Extension for sequences of dictionaries where the values are Equatable
A [String: Equatable]
is a mapping of strings to any Equatable type. There is no promise that each value be the same equatable type. That said, it's not actually possible to create such a dictionary (since Equatable
has an associated type), so this extension cannot apply to any actual type in Swift. (The fact that you don't receive an error here is IMO a bug in the compiler.)
The feature you'd need to make this work is SE-0142, which is accepted, but not implemented. You currently cannot constrain an extension based on type constraints this way.
There are many ways to achieve what you're trying to do. One straightforward way is to pass your equality function:
extension Sequence {
public func removeDoubles(with equal: (Iterator.Element, Iterator.Element) -> Bool) -> [Iterator.Element] {
var noDoubles: [Iterator.Element] = []
for item in self {
if !noDoubles.contains(where: { equal($0, item) }) {
noDoubles.append(item)
}
}
return noDoubles
}
}
let noDupes = dict.removeDoubles(with: { $0["name"] == $1["name"] })
This is slightly different than your code in how it behaves when name
is missing, but slight tweaks could get what you want.
That said, the need for this strongly suggests an incorrect data model. If you have this sequence of dictionaries, and you're trying to build an extension on that, you almost certainly meant to have a sequence of structs. Then this becomes more straightforward. The point of a dictionary is an arbitrary mapping of keys to values. If you have a small set of known keys that are legal, that's really a struct.
How to use compact map on custom type?
You can use .reduce(into:_:)
:
let dictionary = all.reduce(into: [:]) { dict, elem in
dict[elem.key] = elem.value
}
Related Topics
Convert Urlrequest to Nsmutableurlrequest
How to Test If "Allow Full Access" Permission Is Granted from Containing App
How to Monitor More Than 20 Regions
Saving Already Created Live Photos
Cannot Set Color of Button's Label Inside Menu in Swiftui
Xcode 12.5 Missing Entitlement Com.Apple.Developer.Associated-Appclip-App-Identifiers
Apple Healthkit - Background Updates Not Triggering
Swiftui Multiple Navigationlinks in Form/Sheet - Entry Stays Highlighted
How Posting One Signal Notification's Additional Data and Receiving That
Swift 3 Nscache Generic Parameter 'Keytype' Could Not Be Inferred
How to Unwrap the Elements of an Array in Swift? (Ie. Array<Int> as Array<Int>)
How to Get the Correct Current Time in iOS
Wake Up Application in Background Using Audiosession Like Alarmy iOS App
Diffabledatasource: Snapshot Doesn't Reload Headers & Footers