简体   繁体   中英

Count number of results from Firebase (Swift)

I have a Firebase Database up and running, which stores data reported by the users of the iOS application; for example, a grocery store can be reported, which is then in turn stored in the database. Next to the name of the store, the time of the report (rounded to 15 minutes) is also stored in the database as reportedTime .

Now I want to find out, at which time of the day – ie morning (06:00 - 12:00 o'clock), noon (12:00 - 18:00 o'clock), evening (18:00 - 24:00 o'clock) or night (00:00 - 06:00 o'clock) – how many reports are filed.

I fetch the values from firebase, store them in a model and hence can access, for example, report.reportTime which returns something like " 2019-07-27 19:30:00 +0000 " as a string for each individual report.

How can I count the number of reports between 00:00:00 and 06:00:00, for example?

I am using SwiftValidators and tried the following (don't judge me!):

if Validator.contains("00:00:00").apply(report.reportTime) || Validator.contains("00:15:00").apply(report.reportTime) || Validator.contains("00:30:00").apply(report.reportTime) || Validator.contains("00:45:00").apply(report.reportTime) || Validator.contains("01:00:00").apply(report.reportTime) || Validator.contains("01:15:00").apply(report.reportTime) || Validator.contains("01:30:00").apply(report.reportTime) || Validator.contains("01:45:00").apply(report.reportTime) || Validator.contains("02:00:00").apply(report.reportTime) || Validator.contains("02:15:00").apply(report.reportTime) || Validator.contains("02:30:00").apply(report.reportTime) || Validator.contains("02:45:00").apply(report.reportTime) || Validator.contains("03:00:00").apply(report.reportTime) || Validator.contains("03:15:00").apply(report.reportTime) || Validator.contains("03:30:00").apply(report.reportTime) || Validator.contains("03:45:00").apply(report.reportTime) || Validator.contains("04:00:00").apply(report.reportTime) || Validator.contains("04:15:00").apply(report.reportTime) || Validator.contains("04:30:00").apply(report.reportTime) || Validator.contains("04:45:00").apply(report.reportTime) || Validator.contains("05:00:00").apply(report.reportTime) || Validator.contains("05:15:00").apply(report.reportTime) || Validator.contains("05:30:00").apply(report.reportTime) || Validator.contains("05:45:00").apply(report.reportTime) {

                    // do something which I don't know

                }

Create an enum TimeOfTheDay in the model Report and initialize the enum based on the hour value. And create a computed property of type TimeOfTheDay in the model.

struct Report {
    enum TimeOfTheDay {
        case morning, noon, evening, night
        init?(_ hour: Int) {
            switch hour {
            case 0...6:
                self = .night
            case 6...12:
                self = .morning
            case 12...18:
                self = .noon
            case 18...24:
                self = .evening
            default:
                return nil
            }
        }
    }
    var id: String
    var reportTime: String
    //...other properties    
    var timeOfTheDay: TimeOfTheDay? {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
        if let date = dateFormatter.date(from: reportTime) {
            let hour = Calendar.current.component(.hour, from: date)
            return TimeOfTheDay(hour)
        }
        return nil
    }
}

Option 1

Now using Dictionary(grouping:by:) method you can group the reports array based on the time of the day value.

var allReports = [Report(id: "a", reportTime: "2019-07-27 01:30:00 +0000"), Report(id: "a", reportTime: "2019-07-27 20:30:00 +0000"),
                  Report(id: "a", reportTime: "2019-07-27 11:30:00 +0000"), Report(id: "a", reportTime: "2019-07-27 03:30:00 +0000"),
                  Report(id: "a", reportTime: "2019-07-27 09:30:00 +0000"), Report(id: "a", reportTime: "2019-07-27 10:30:00 +0000"),
                  Report(id: "a", reportTime: "2019-07-27 15:30:00 +0000"), Report(id: "a", reportTime: "2019-07-27 07:30:00 +0000")]
var groupedReports = Dictionary(grouping: allReports) { $0.timeOfTheDay }
print(groupedReports)
//[night: [Report(id: "a", reportTime: "2019-07-27 20:30:00 +0000")],
// morning: [Report(id: "a", reportTime: "2019-07-27 01:30:00 +0000"), Report(id: "a", reportTime: "2019-07-27 03:30:00 +0000")],
// noon: [Report(id: "a", reportTime: "2019-07-27 11:30:00 +0000"), Report(id: "a", reportTime: "2019-07-27 09:30:00 +0000"),
//        Report(id: "a", reportTime: "2019-07-27 10:30:00 +0000"), Report(id: "a", reportTime: "2019-07-27 07:30:00 +0000")],
// evening: [Report(id: "a", reportTime: "2019-07-27 15:30:00 +0000")]]

You can get the morning only reports from the dictionary

print(groupedReports[Report.TimeOfTheDay.morning])
//[Report(id: "a", reportTime: "2019-07-27 01:30:00 +0000"),Report(id: "a", reportTime: "2019-07-27 03:30:00 +0000")]

Option 2

Use filter(_:) method to get morning only reports

let morningReports = allReports.filter { $0.timeOfTheDay == Report.TimeOfTheDay.morning }
print(morningReports)
//[Report(id: "a", reportTime: "2019-07-27 01:30:00 +0000"), Report(id: "a", reportTime: "2019-07-27 03:30:00 +0000")]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM