1

From the below 8 bit, I want to understand which days are active. But I could not come up with a proper solution.

0b00101101
   |     |
   |     Monday
   Sunday

What I tried is:

func getWorkingDays(_ value: Data?) -> String? {
    guard let value = value else { return nil }
    if value.count == 1 {
        let days = calculateDays(value[0])
        return days
    }
    return nil
}

func calculateDays(_ days: UInt8?) -> String? {
        switch days {
        case 1:
            return "Monday"
        case 2:
            return "Tuesday"
        case 3:
            return "Monday, Tuesday"
        case 4:
            return "Wednesday"
        ......
}
serdar aylanc
  • 1,307
  • 2
  • 20
  • 37
  • 1
    https://stackoverflow.com/questions/24112347/declaring-and-using-a-bit-field-enum-in-swift ? If you are looking for others answers, some interesting keywords: bit, field, flags, enum... – Larme Jul 24 '18 at 14:35
  • You can declare the days as their own binary values. for example `let monday = 0b00000001` and then `if( (days | monday) == days) { // monday is on` – Wamadahama Jul 24 '18 at 15:03

2 Answers2

4

You want to look at using a OptionSet.

You use the OptionSet protocol to represent bitset types, where individual bits represent members of a set.

In your case it would look something like this.

struct Weekdays: OptionSet {
    let rawValue: Int

    static let monday    = Weekdays(rawValue: 1 << 0)
    static let tuesday   = Weekdays(rawValue: 1 << 1)
    static let wednesday = Weekdays(rawValue: 1 << 2)
    static let thrusday  = Weekdays(rawValue: 1 << 3)
    static let friday    = Weekdays(rawValue: 1 << 4)
    static let saturday  = Weekdays(rawValue: 1 << 5)
    static let sunday    = Weekdays(rawValue: 1 << 6)
}

Then to convert from an Int to Weekdays you do

let data = 0b00101101
let weekdays = Weekdays(rawValue: data)

And to check if it contains a certain day or multiple days you do

if weekdays.contains(.monday) {
    print("It's monday!")
}
Craig Siemens
  • 12,942
  • 1
  • 34
  • 51
0

Simple solution, it shifts the bits bitwise to the right, masks all bits except the rightmost and check if it's 1 or 0, then get the weekday name from an array by the loop index.

For example

i = 00b00101101 → index 0 (Monday).
i = 10b00010110
i = 20b00001011 → index 2 (Wednesday)

etc.


let weekdays = Calendar.current.weekdaySymbols // starts with `Sunday` will be adjusted with (i+1)%7

let activeDays = 0b00101101

var activeWeekdays = [String]()
for i in 0..<7 {
    if activeDays >> i & 0x1 == 1 { activeWeekdays.append(weekdays[(i + 1) % 7]) }
}
print(activeWeekdays) // ["Monday", "Wednesday", "Thursday", "Saturday"]
vadian
  • 274,689
  • 30
  • 353
  • 361