我对此措辞有困难,但现在就去了。
我有一组Datapoint
个对象,每个对象都有一个createdAt
NSDate
属性。该数组在过去一周的每一天都有大约10个Datapoint
个对象。
我想过滤数组,以便每周的每一天只有一个数据点。
我正在思考以下几点:
let today = NSDate()
var endRange = today.dateByAddingTimeInterval(-7 * 24 * 60 * 60)
var allThisWeeksPoints = datapoints.filter({ $0.createdAt >= endRange && $0.createdAt < today })
let c = NSCalendar.currentCalendar()
var thisWeeksPoints : [Datapoint] = []
while !c.isDate(endRange, inSameDayAsDate: today) {
//take one datapoint, eliminate all the other datapoints in the same day and then increment the endRange date by a day
}
以下是我的Datapoint对象的代码:
class Datapoint: NSObject {
let object : PFObject
let objectId : String
let userId : String
let createdAt : NSDate
let totalPosts : Int
let followerCount : Int
let followingCount : Int
let totalLikes : Int
let averageLikes : Float
let totalComments : Int
let averageComments : Float
}
答案 0 :(得分:1)
第一步:
制作NSDate
Comparable
Found here
public func ==(lhs: NSDate, rhs: NSDate) -> Bool {
return lhs === rhs || lhs.compare(rhs) == .OrderedSame
}
public func <(lhs: NSDate, rhs: NSDate) -> Bool {
return lhs.compare(rhs) == .OrderedAscending
}
extension NSDate: Comparable { }
一些一般性评论:
将功能拆分为两部分,一部分用于将点分为几周,另一部分用于应用滤波器。这使得维护更容易。
根据评论中的建议使用dateByAddingUnit
。这将防止本地化问题。并非每个星期都是相同的,并非世界上使用的每个日历都使用相同的周数系统。
func weeklyPoints(dataPoints: [DataPoint]) -> [[DataPoint]]? {
guard let firstPoint = dataPoints.first else { // alternative to an .isEmpty check since we need the first point anyway
return nil
}
guard let gregorian = NSCalendar(identifier:NSCalendarIdentifierGregorian) else {
return nil
}
var weeklies : [[DataPoint]] = [[]]
var weekStart : NSDate = firstPoint.createdAt // force unwrap allowed because of the guard at the beginning
var maybeWeekEnd : NSDate? = gregorian.dateByAddingUnit(.WeekOfYear, value: 1, toDate: weekStart, options: [])
for point in dataPoints {
guard let weekEnd = maybeWeekEnd else {
break
}
guard point.createdAt >= weekStart && point.createdAt < weekEnd else {
weekStart = weekEnd
maybeWeekEnd = gregorian.dateByAddingUnit(.WeekOfYear, value: 1, toDate: weekStart, options: [])
weeklies.append([])
continue
}
let currentWeekIndex = (weeklies.count - 1)
weeklies[currentWeekIndex].append(point)
}
return weeklies
}
非常简单的过滤功能。
func onePointPerWeek(dataPoints: [DataPoint]) -> [DataPoint]? {
guard let weeklies = weeklyPoints(dataPoints) else {
return nil
}
var pointPerWeek : [DataPoint] = []
for week in weeklies {
guard let point = week.first else { // maybe sort them first if needed
continue
}
pointPerWeek.append(point)
}
return pointPerWeek
}
答案 1 :(得分:0)
所以我找到了一种方法:
func thisWeeksPoints() -> [Datapoint] {
let today = NSDate()
var endRange = today.dateByAddingTimeInterval(-7 * 24 * 60 * 60)
var allThisWeeksPoints = datapoints.filter({ $0.createdAt >= endRange && $0.createdAt < today })
let c = NSCalendar.currentCalendar()
var thisWeeksPoints : [Datapoint] = []
while !c.isDate(endRange, inSameDayAsDate: today) {
if let point = allThisWeeksPoints.first {
allThisWeeksPoints = allThisWeeksPoints.filter({!c.isDate(point.createdAt, inSameDayAsDate: $0.createdAt)})
thisWeeksPoints.append(point)
}
endRange = endRange.dateByAddingTimeInterval(24 * 60 * 60)
}
return thisWeeksPoints
}