根据属性值过滤数组

时间:2015-07-23 08:48:36

标签: ios arrays swift filtering

有两个名为EventAgenda的课程。

class Event {
    let id: Int
    var title: String
    var allDay: Int = 0
    let location: String
    var description: String?
    var startDate: NSDate!
    var endDate: NSDate!
}

class Agenda {
    var date: NSDate!
    var events = [Event]()
}

我有一组这些Event个对象。

我需要根据它的startDate属性过滤掉这个事件数组。

例如说有11个事件。 (我只在这里显示startDates)

2015-07-20
2015-07-21
2015-07-21
2015-07-22
2015-07-22
2015-07-22
2015-07-23
2015-07-23
2015-07-24
2015-07-24
2015-07-24

我需要过滤此数组并创建一个Agenda个对象的数组。像这样。

+------------+----------------+
|    date    | events (count) |
+------------+----------------+
| 2015-07-20 |              1 |
| 2015-07-21 |              2 |
| 2015-07-22 |              3 |
| 2015-07-23 |              2 |
| 2015-07-24 |              3 |
+------------+----------------+

我尝试遍历events数组并按下面的方式执行。

public func filterByDate(events: [Event]) {
    var agendas = [Agenda]()
    for event in events {
        if agendas.isEmpty {
            var agenda = Agenda()
            agenda.date = event.startDate!
            agenda.events.append(event)

            agendas.append(agenda)
        } else {
            let lastAgenda = agendas.last!
            let lastEventOfLastAgenda = lastAgenda.events.last!

            if isSameDate(date1: event.startDate!, date2: lastEventOfLastAgenda.startDate!) {
                lastAgenda.events.append(event)
            } else {
                var agenda = Agenda()
                agenda.date = event.startDate!
                agenda.events.append(event)

                agendas.append(agenda)
            }
        }
    }
}

func isSameDate(#date1: NSDate, date2: NSDate) -> Bool {
    let calendar = NSCalendar.currentCalendar()
    let components: NSCalendarUnit = .CalendarUnitDay | .CalendarUnitMonth | .CalendarUnitYear

    let date1Components = calendar.components(components, fromDate: date1)
    let date2Components = calendar.components(components, fromDate: date2)

    let date1 = calendar.dateFromComponents(date1Components)!
    let date2 = calendar.dateFromComponents(date2Components)!
    let result = date1.compare(date2)
    if result == NSComparisonResult.OrderedSame {
        return true
    }
    return false
}

但我得到的结果不正确。我在agendas数组中得到了6个对象。当我只是迭代它时,我得到以下输出。

2015-07-20  -   1
2015-07-21  -   1
2015-07-21  -   2
2015-07-22  -   4
2015-07-24  -   1
2015-07-24  -   2

我无法弄清楚它出了什么问题。任何帮助将不胜感激。

顺便说一句,即使我使用这种方法,它仍然非常凌乱,而且不是很像 Swift-like 。在Swift中有更优雅的方法吗?

2 个答案:

答案 0 :(得分:1)

尝试更优雅的方式:

var events: [Event] = Your Event Array Here ...

var groupedDates: [NSDate: Int] = [:] 

for event in events {
    if let number = groupedDates[event.startDate] {
        groupedDates[event.startDate] = number + 1
    }else{
        groupedDates[event.startDate] = 1
    }
}

println(groupedDates)

答案 1 :(得分:0)

修改:我通过向itit()课程添加Agenda进一步简化了此操作。我相信这简洁地完成了你的要求(这是Xcode 7 beta 4中的Swift 2)。它会创建一个名为Agenda的{​​{1}}个对象[Agenda]数组。

假设我们有一组名为agendaArray的{​​{1}}个对象,其中Event在您的问题中被声明。

这是我的解决方案:

eventArray

以下是修改后的Event类:

var agendaArray = [Agenda]()
for date in Set(eventArray.filter{$0.startDate != nil}.map{$0.startDate}) {
    agendaArray.append(Agenda(date: date, events: eventArray.filter({$0.startDate == date})))
} // populates [Agenda] for each unique date

快速测试它(首先必须按日期排序,因为结果数组没有固定的顺序):

Agenda