如何解决在 Swift 中使用相同的值对一周中的几天进行分组
我有一个服务请求,其中包含一个名为“hoursArray”的数组中的商店时间表,格式如下:
"hours": [
"00:00-23:59", "00:00-23:59", "00:00-21:59", "00:00-22:59", "00:00-22:59", "00:00-23:59"
]
我在包含两个垂直堆栈视图的水平堆栈视图中显示此信息,一个带有一周中 7 天的标签,另一个带有当天日程表的七个标签,我用这个函数填充这个标签:
func getSchedule(){
scheduleLabel1.text = hoursArray[0] as? String
scheduleLabel2.text = hoursArray[1] as? String
scheduleLabel3.text = hoursArray[2] as? String
scheduleLabel4.text = hoursArray[3] as? String
scheduleLabel5.text = hoursArray[4] as? String
scheduleLabel6.text = hoursArray[5] as? String
scheduleLabel7.text = hoursArray[6] as? String
dayLabel1.text = "Monday"
dayLabel2.text = "Tuesday"
dayLabel3.text = "Wednesday"
dayLabel4.text = "Thursday"
dayLabel5.text = "Friday"
dayLabel6.text = "Saturday"
dayLabel7.text = "Sunday"
}
我需要的是将相关天数分组以在我收到具有相同值的天数的请求响应时显示它,例如,如果星期一和星期二具有相同的值,我将在 day1Label 中显示“星期一 - 星期二”。 scheduleLabel1.text 中的文本及其日程安排,我该怎么做?
解决方法
一种方法是这样的,首先按小时范围对数据进行分组:
let hourRanges = [
"00:00-23:59","00:00-23:59","00:00-21:59","00:00-22:59","00:00-23:59"
]
let weekDays = [
"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday",]
struct WeekDaysHourRange {
let hourRange: String
var weekDays: [String]
}
var daysRanges: [WeekDaysHourRange] = []
// assuming both arrays have the same length,otherwise checks are needed
var previousWeekDayRange: WeekDaysHourRange?
for i in 0...6 {
let hourRange = hourRanges[i]
let weekDay = weekDays[i]
if previousWeekDayRange?.hourRange == hourRange {
daysRanges[daysRanges.count - 1].weekDays.append(weekDay)
} else {
let newWeekDayRange = WeekDaysHourRange(hourRange: hourRange,weekDays: [weekDay])
previousWeekDayRange = newWeekDayRange
daysRanges.append(newWeekDayRange)
}
}
为了更新 UI,我将创建 UILabels 数组,以允许使用 for 循环轻松填充标签,如下所示:
let scheduleLabels: [UILabel] = [
scheduleLabel1,scheduleLabel2,scheduleLabel3,scheduleLabel4,scheduleLabel5,scheduleLabel6,scheduleLabel7
]
let dayLabels: [UILabel] = [
dayLabel1,dayLabel2,dayLabel3,dayLabel4,dayLabel5,dayLabel6,dayLabel7
]
daysRanges.enumerated().forEach { (i,weekDayHourRange) in
var daysString: String
if weekDayHourRange.weekDays.count == 1 {
daysString = weekDayHourRange.weekDays.first!
} else {
daysString = "\(weekDayHourRange.weekDays.first!) - \(weekDayHourRange.weekDays.last!)"
}
dayLabels[i].text = daysString
scheduleLabels[i].text = weekDayHourRange.hourRange
}
按照 Joakim Danielson 的评论,如果您只需要创建一次视图而不更新它,您可以即时创建视图:
daysRanges.enumerated().forEach { (i,weekDayHourRange) in
var daysString: String
if weekDayHourRange.weekDays.count == 1 {
daysString = weekDayHourRange.weekDays.first!
} else {
daysString = "\(weekDayHourRange.weekDays.first!) - \(weekDayHourRange.weekDays.last!)"
}
let dayLabel = UILabel()
dayLabel.text = daysString
let scheduleLabel = UILabel()
scheduleLabel.text = weekDayHourRange.hourRange
dayLabelsStackView.addArrangedSubview(dayLabel)
scheduleLabelsStackView.addArrangedSubview(scheduleLabel)
}
这将输出如下内容:
"Monday - Tuesday - 00:00-23:59"
"Wednesday - Thursday - 00:00-21:59"
"Friday - Saturday - 00:00-22:59"
"Sunday - 00:00-23:59"
,
您可以使用以下函数来格式化
let hours = [
"00:00-23:59","00:00-23:59"
]
let days = ["Monday","Sunday"]
func format() -> [(String,String)] {
var temp: [(String,String)] = []
for i in 0..<hours.count {
temp.append((days[i],hours[i]))
}
var result: [(String,String)] = []
var index = 0
var dayStart: String?
var dayEnd: String?
var time: String?
while index < temp.count {
if dayStart == nil {
dayStart = temp[index].0
time = temp[index].1
}
if (index != temp.count - 1) && (temp[index].1 == temp[index+1].1) {
dayEnd = temp[index+1].0
index += 1
}
else {
if let start = dayStart,let tm = time {
if let end = dayEnd {
result.append(("\(start)-\(end)",tm))
dayEnd = nil
}
else {
result.append((start,tm))
}
dayStart = nil
time = nil
}
index += 1
}
}
return result
}
由此您将获得格式化的结果,然后您可以将这些结果作为输入传递给 TableView 或 IBOutletCollection。不建议为这些使用静态标签,因为标签数量可能会改变 b/w 1-7。所以最好使用Tableview。
,已经有一些不错的答案,但是阅读本文似乎功能方法很适合处理输入。这种方法使用 zip 将两个数据集组合成一个元组数组,然后减少以合并它们,并使用一些模式匹配将字符串分解成所需的形状。最后,它使用 map 遍历结果数组,将合并的项添加到堆栈视图中。
let days = ["Monday","Sunday"
]
let hours = [
"00:00-23:59","00:00-23:59"
]
zip(days,hours)
.reduce([(String,String)]()){
guard let last = $0.last else {return [$1]}
if last.1 == $1.1 {
var days = last.0
if let lastDayRange = days.range(of: #"(?<=- )[A-Z,a-z]*day"#,options: .regularExpression) {
days.replaceSubrange(lastDayRange,with: $1.0)
} else {
days = days + " - \($1.0)"
}
return $0.dropLast() + [(days,$1.1)]
} else {
return $0 + [$1]
}
}
.map{
let dayLabel = UILabel()
let hoursLabel = UILabel()
dayLabel.text = $0.0
hoursLabel.text = $0.1
daysStack.addArrangedSubview(dayLabel) //or whatever the stackview is called
hoursStack.addArrangedSubview(hoursLabel)
}
UI 部分很简单,需要更多内容才能获得所需的输出,但应该足以入门。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。