如果当前时间在TimeRange之内,则过滤数组 [英] Filter Array if Current Time is within TimeRange
问题描述
我当前的函数过滤该数组,并返回一个只有"Type"
= "Sushi"
的PFObjects
数组.现在,我如果当前时间在一个时间范围("OpenHours"
和"CloseHours"
)之内,尝试过滤数组
新功能通过dayOfWeek: Int
,timeNow: String
My current function filters the array and returns an array of PFObjects
with only "Type"
= "Sushi"
. Now, I am trying to filter the array if current time is within a time range ("OpenHours"
and "CloseHours"
)
The new Function passes dayOfWeek: Int
, timeNow: String
"OpenHours"示例:[0,6] = [星期日,星期一]
"OpenHours" Example: [0, 6] = [sunday, monday]
["0011","0011","0011","0011","0011","0011","0011"]
"CloseHours"示例:
"CloseHours" Example:
["2350","2350","2350","2350","2350","2350","2350"]
过滤类型"的当前功能:
Current Function that filters "Type":
func filterRestaurants(filteredObject: String) {
//func filterOpenNow(dayOfWeek: Int, timeNow: String){
filteredRestaurantArray = unfilteredRestaurantArray.filter() {
if let type = ($0 as PFObject)["Type"] as? String { // Get value of PFObject
return type.rangeOfString("Sushi") != nil
} else {
println("nope")
return false
}
}
基本上,对于给定的dayOfWeek
修改: 到目前为止,我尝试过的是: 我不确定如何获取值在PFObject数组中的位置.正常,我会检查timeNow是否介于OpenNow [dayOfWeek]和CloseNow [dayOfWeek]之间
What I've Tried so far: I'm unsure how to get the position of a value in the PFObject array. Normal I would check if the timeNow is between OpenNow[dayOfWeek] and CloseNow[dayOfWeek]
类似这样的东西(带过滤器的除外):
Something like this (except with filter):
if OpenNow[dayOfWeek] ... CloseNow[dayOfWeek] ~= timeNow {
println("success")
}
推荐答案
我不确定您的PFObject
实例的属性是什么,因此我要作一些假设,您将必须更正密钥满足您的需求.
I am not entirely sure what the properties of your PFObject
instance are, so I'm going to make some assumptions and you will have to correct the keys to meet your needs.
使用您提供的功能签名不是完全可能的.这是因为要使其正常工作,您将访问未提供给该功能的PFObject
列表.尽管Swift不能阻止您这样做,但是通常这不是一个明智的设计选择,因为您无法在任何给定的时间点都对函数的结果充满信心.因此,为了提供所谓的参照透明性,我们将修改您的函数以同时使用PFObject
s的集合.
Working with the function signature you provided is not entirely possible. This is because in order for it to work you would be accessing a list of PFObject
s that were not provided to the function. While Swift does not keep you from doing that, it is generally not a wise design choice as you cannot be confident of the results of the function at any given point in time. So, to provide what is called referential transparency we will modify your function to also take in the collection of PFObject
s.
然后使用该集合,我们将使用本机filter
函数来确定要从该函数返回的函数. filter
函数接受一个集合和一个闭包.闭包采用一个参数(集合的一个元素),并返回Bool
.闭包是确定元素是否保留或丢弃的原因.
With that collection we will then use the native filter
function to determine which ones to return from the function. The filter
function takes a collection and a closure. The closure takes one parameter, an element of the collection, and return a Bool
. The closure is what determines if an element is kept or discarded.
认识到这一点,我们可以构建您要求的功能.我不能保证在开始时没有更好的方法来进行第一个if let
舞蹈,但是它应该可以完成工作.
Knowing that, we can build up the functionality you requested. I cannot guarantee there isn't a better way to do the first if let
dance at the beginning, but it should get the job done.
func filterAreOpen(restaurants: [PFObject], forTime time: String, onDay day: Int) -> [PFObject] {
let openRests = filter(restaurants) { r in
if let openHours = r["OpenHours"] as AnyObject? as? [String] {
if let closeHours = r["CloseHours"] as AnyObject? as? [String] {
switch (openHours[day].toInt(), closeHours[day].toInt(), time.toInt()) {
case let (.Some(oh), .Some(ch), .Some(t)):
return oh...ch ~= t
default:
return false
}
}
}
return false
}
return openRests
}
您将像这样使用它
let rests = [ // example objects that are replaced by your PFObject instances
[
"OpenHours":["0011","0012","0013"],
"CloseHours":["0023","0023","0023"],
"Name":"Restaurant1"
],
[
"OpenHours":["0014","0015","0016"],
"CloseHours":["0020","0020","0020"],
"Name":"Restaurant2"
]
]
let openRestaurants = filterAreOpen(rests, forTime: "0012", onDay: 1)
/* Results
[{
CloseHours = (
0023,
0023,
0023
);
Name = Restaurant1;
OpenHours = (
0011,
0012,
0013
);
}]
*/
关于封闭内的switch
的简要说明.在Swift中,switch
语句比Objective-C时代要强大得多.它能够将值与模式匹配,而不仅仅是数字.
A quick explanation about the switch
inside the closure. In Swift the switch
statement is much more powerful than it was in the Objective-C days. It is capable of matching a value against a pattern, not just numbers.
因此,在这种情况下,switch
与Int?
,(Int?, Int?, Int?)
的三元组匹配.这是因为String
的toInt()
方法返回一个Int?
. switch
还能够将匹配的模式绑定到局部范围的常量.为此,我们使用let
关键字.要对Optional
值进行模式匹配,请使用.Some(x)
模式.因为我们有一个三元组,所以我们使用.Some(x)
三次,用<有意义的名称替换x
.这样,如果将三个toInt()
调用评估为非nil
值,则可以访问我们感兴趣的三个值.
So, in this case, the switch
is matching a 3-tuple of Int?
, (Int?, Int?, Int?)
. This is because String
's toInt()
method returns an Int?
. switch
is also able to bind matched patterns to local scoped constants. To do that we use the let
keyword. To pattern match on an Optional
value, you use the .Some(x)
pattern. Since we have a 3-tuple we use .Some(x)
three time, with the x
replaced by some meaningful name. This way we have access to the three values we are interested in if the three toInt()
calls evaluated to non-nil
values.
如果任何String
值都不能等于Int
,nil
也是如此,则使用default
大小写,并返回false.
If any of the String
values could not evaluate to an Int
, and so was nil
, the default
case is used, and returns false.
您可以在条件语句 查看全文