如果当前时间在 TimeRange 内,则过滤数组
Filter Array if Current Time is within TimeRange
我当前的函数过滤数组 returns 一个 PFObjects
的数组,只有 "Type"
= "Sushi"
。现在,如果当前时间在时间范围内("OpenHours"
和 "CloseHours"
),我正在 尝试过滤数组
新函数通过 dayOfWeek: Int
、timeNow: String
"OpenHours" 示例:[0, 6] = [星期日, 星期一]
["0011","0011","0011","0011","0011","0011","0011"]
"CloseHours" 示例:
["2350","2350","2350","2350","2350","2350","2350"]
过滤"Type"的当前函数:
func filterRestaurants(filteredObject: String) {
//func filterOpenNow(dayOfWeek: Int, timeNow: String){
filteredRestaurantArray = unfilteredRestaurantArray.filter() {
if let type = ([=12=] as PFObject)["Type"] as? String { // Get value of PFObject
return type.rangeOfString("Sushi") != nil
} else {
println("nope")
return false
}
}
基本上,对于给定的 dayOfWeek
,我需要过滤当前时间 timeNow
介于 OpenHours
和 CloseHours
之间的对象
编辑:
到目前为止我尝试过的:
我不确定如何获取值在 PFObject 数组中的位置。正常我会检查 timeNow 是否在 OpenNow[dayOfWeek] 和 CloseNow[dayOfWeek]
之间
像这样(除了过滤器):
if OpenNow[dayOfWeek] ... CloseNow[dayOfWeek] ~= timeNow {
println("success")
}
我不完全确定你的 PFObject
实例的属性是什么,所以我将做一些假设,你必须更正密钥以满足你的需要。
无法完全使用您提供的函数签名。这是因为为了使其正常工作,您将访问未提供给函数的 PFObject
列表。虽然 Swift 不会阻止你这样做,但它通常不是一个明智的设计选择,因为你无法在任何给定时间点对函数的结果充满信心。因此,为了提供所谓的 referential transparency,我们将修改您的函数以同时接收 PFObject
s.
的集合。
对于该集合,我们将使用本机 filter
函数来确定从该函数中 return 哪些。 filter
函数接受一个集合和一个闭包。闭包接受一个参数,一个集合的元素,和return一个Bool
。闭包决定了一个元素是被保留还是被丢弃。
知道了这一点,我们就可以构建您所请求的功能。我不能保证没有更好的方法来开始第一个 if let
舞蹈,但它应该完成工作。
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 时代强大得多。它能够将值与模式进行匹配,而不仅仅是数字。
因此,在这种情况下,switch
匹配 Int?
、(Int?, Int?, Int?)
的三元组。这是因为 String
的 toInt()
方法 return 是 Int?
。 switch
还能够将匹配的模式绑定到局部范围的常量。为此,我们使用 let
关键字。要对 Optional
值进行模式匹配,请使用 .Some(x)
模式。因为我们有一个 3 元组,所以我们使用 .Some(x)
三次,x
替换为一些有意义的名称。这样,如果三个 toInt()
调用评估为非 nil
值,我们就可以访问我们感兴趣的三个值。
如果任何 String
值无法计算为 Int
,nil
也是如此,则使用 default
情况,并且 return是假的。
您可以查看有关条件语句的语言书籍here。
我当前的函数过滤数组 returns 一个 PFObjects
的数组,只有 "Type"
= "Sushi"
。现在,如果当前时间在时间范围内("OpenHours"
和 "CloseHours"
),我正在 尝试过滤数组
新函数通过 dayOfWeek: Int
、timeNow: String
"OpenHours" 示例:[0, 6] = [星期日, 星期一]
["0011","0011","0011","0011","0011","0011","0011"]
"CloseHours" 示例:
["2350","2350","2350","2350","2350","2350","2350"]
过滤"Type"的当前函数:
func filterRestaurants(filteredObject: String) {
//func filterOpenNow(dayOfWeek: Int, timeNow: String){
filteredRestaurantArray = unfilteredRestaurantArray.filter() {
if let type = ([=12=] as PFObject)["Type"] as? String { // Get value of PFObject
return type.rangeOfString("Sushi") != nil
} else {
println("nope")
return false
}
}
基本上,对于给定的 dayOfWeek
timeNow
介于 OpenHours
和 CloseHours
之间的对象
编辑: 到目前为止我尝试过的: 我不确定如何获取值在 PFObject 数组中的位置。正常我会检查 timeNow 是否在 OpenNow[dayOfWeek] 和 CloseNow[dayOfWeek]
之间像这样(除了过滤器):
if OpenNow[dayOfWeek] ... CloseNow[dayOfWeek] ~= timeNow {
println("success")
}
我不完全确定你的 PFObject
实例的属性是什么,所以我将做一些假设,你必须更正密钥以满足你的需要。
无法完全使用您提供的函数签名。这是因为为了使其正常工作,您将访问未提供给函数的 PFObject
列表。虽然 Swift 不会阻止你这样做,但它通常不是一个明智的设计选择,因为你无法在任何给定时间点对函数的结果充满信心。因此,为了提供所谓的 referential transparency,我们将修改您的函数以同时接收 PFObject
s.
对于该集合,我们将使用本机 filter
函数来确定从该函数中 return 哪些。 filter
函数接受一个集合和一个闭包。闭包接受一个参数,一个集合的元素,和return一个Bool
。闭包决定了一个元素是被保留还是被丢弃。
知道了这一点,我们就可以构建您所请求的功能。我不能保证没有更好的方法来开始第一个 if let
舞蹈,但它应该完成工作。
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 时代强大得多。它能够将值与模式进行匹配,而不仅仅是数字。
因此,在这种情况下,switch
匹配 Int?
、(Int?, Int?, Int?)
的三元组。这是因为 String
的 toInt()
方法 return 是 Int?
。 switch
还能够将匹配的模式绑定到局部范围的常量。为此,我们使用 let
关键字。要对 Optional
值进行模式匹配,请使用 .Some(x)
模式。因为我们有一个 3 元组,所以我们使用 .Some(x)
三次,x
替换为一些有意义的名称。这样,如果三个 toInt()
调用评估为非 nil
值,我们就可以访问我们感兴趣的三个值。
如果任何 String
值无法计算为 Int
,nil
也是如此,则使用 default
情况,并且 return是假的。
您可以查看有关条件语句的语言书籍here。