[swift-users] Reducing Array<OptionSet> to OptionSet

Jon Shier jon at jonshier.com
Thu Nov 3 20:53:12 CDT 2016


	Yes, just in a generic fashion. I don’t have so many OptionSets to decode that writing the typed reduce code over and over again is terrible, I just hoped there would be a way to write it generically. I just can’t seem to get the types to work out. I’m just missing the final step, generically reducing an array of OptionSet values to a single OptionSet value.


Jon

> On Nov 3, 2016, at 9:48 PM, Erica Sadun <erica at ericasadun.com> wrote:
> 
> Like this?
> 
> let sets: [MyOptionSet] = [MyOptionSet(strings: ["one"]), MyOptionSet(strings: ["two"]), MyOptionSet(strings: ["one", "two"])]
> let unioned = sets.reduce(MyOptionSet(rawValue: 0)) {
>     (result, set) in return result.union(set)
> }
> unioned.rawValue
> 
> 
>> On Nov 3, 2016, at 7:44 PM, Jon Shier <jon at jonshier.com <mailto:jon at jonshier.com>> wrote:
>> 
>> Thanks Erica. I’ve been able to transform arrays of strings into arrays of my OptionSets using an enum approach like you describe. I was looking more for a generic approach that I could apply to all of the various OptionSets I have to decode from JSON. I suppose whether it’s from an array of strings or array of the OptionSet is less important, but getting to the array of the OptionSet itself is something I can already do. 
>> 
>> 
>> Thanks,
>> 
>> Jon
>> 
>>> On Nov 3, 2016, at 9:37 PM, Erica Sadun <erica at ericasadun.com <mailto:erica at ericasadun.com>> wrote:
>>> 
>>> Maybe something like this? Or you could just bitwise || individual sets. Or you could use a dictionary to lookup [string: rawValue]. etc.
>>> 
>>> public struct MyOptionSet: OptionSet {
>>>     public static let one = MyOptionSet(rawValue: 1 << 0)
>>>     public static let two = MyOptionSet(rawValue: 1 << 1)
>>>     public static let three = MyOptionSet(rawValue: 1 << 2)
>>>     
>>>     public var rawValue: Int { return _rawValue }
>>>     public init(rawValue: Int) { self._rawValue = rawValue }
>>>     private let _rawValue: Int
>>>     
>>>     private enum StringEnum: String { case one, two, three }
>>>     public init(strings: [String]) {
>>>         var set = MyOptionSet()
>>>         strings.flatMap({ StringEnum(rawValue: $0) })
>>>             .flatMap({ MyOptionSet(rawValue: 1 << $0.hashValue) })
>>>             .forEach { set.insert($0) }
>>>         _rawValue = set.rawValue
>>>     }
>>> }
>>> 
>>> let stringArray: [String] = ["one", "three"]
>>> let stringOptions = MyOptionSet(strings: stringArray)
>>> stringOptions.rawValue
>>> 
>>>> On Nov 3, 2016, at 7:09 PM, Jon Shier via swift-users <swift-users at swift.org <mailto:swift-users at swift.org>> wrote:
>>>> 
>>>> Swifters:
>>>> 	I’m dealing with a JSON API where sets of options are returned as arrays of strings. Representing these as OptionSets seems ideal. I can decode the arrays of strings into an array of individual OptionSet values, but I’ve run into a dead end when trying generically reduce the array of OptionSets to a single OptionSet value. I’ve tried variety of ways of definition a Collection extension, even tried defining a global function, but I can’t seem to use the OptionSet sequence initializer or reduce itself (cannot invoke insert with argument of type (OptionSet) (or T)). Any guidance here? 
>>>> 	Here’s what I’ve tried:
>>>> 
>>>> extension Collection where Iterator.Element == OptionSet {
>>>> 
>>>>    func reduced() -> Iterator.Element {
>>>>        return reduce(Iterator.Element()) {
>>>>            var newResult = $0
>>>>            newResult.insert($1)
>>>>            return newResult
>>>>        }
>>>>    }
>>>> 
>>>> }
>>>> 
>>>> extension Collection where Iterator.Element == OptionSet {
>>>> 
>>>>    func reduced<T: OptionSet>() -> T {
>>>>        return reduce(T()) {
>>>>            var newResult = $0
>>>>            newResult.insert($1)
>>>>            return newResult
>>>>        }
>>>>    }
>>>> 
>>>> }
>>>> 
>>>> 
>>>> extension Collection where Iterator.Element == OptionSet {
>>>>    func reduced() -> Iterator.Element {
>>>>        return Iterator.Element(self)
>>>>    }
>>>> }
>>>> 
>>>> func reduced<T: OptionSet>(_ options: [T]) -> T {
>>>>    return options.reduce(T()) {
>>>>        var newResult = $0
>>>>        newResult.insert($1)
>>>> 
>>>>        return newResult
>>>>    }
>>>> }
>>>> 
>>>> Jon Shier
>>>> _______________________________________________
>>>> swift-users mailing list
>>>> swift-users at swift.org <mailto:swift-users at swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-users <https://lists.swift.org/mailman/listinfo/swift-users>
>>> 
>> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20161103/3603fb54/attachment.html>


More information about the swift-users mailing list