最近有人問我這樣一個邏輯,應該怎么實現,挺有意思的,就在這里記錄一下:
他的需求是這樣的:
如上圖中(界面太丑,請忽略??),是一組連續的數據( 當然實際不是這些數字,是其他的一些內容,但是他要記錄的只是這些連續的區間,所以無所謂數據內容了).用戶自由選擇,選中的為紅色,最后確定的時候,每個連續的區間形成一個model,記錄當前區間的開始索引及長度.
第一感覺是,這挺簡單的,就是一個選擇排序分組的功能嘛,但是實現起來,還是挺繞的,我簡單的做了這么個界面,整體是一個UICollectionView然后實現選中與未選中的狀態,下面這是cell的點擊方法中,選擇數據的邏輯:
let cell = collectionView.cellForItem(at: indexPath) as! LessionCell
let lesson = self.dataSource[indexPath.row]
if lesson.state == .selected {
lesson.state = .unSelected
} else if lesson.state == .unSelected{
lesson.state = .selected
}
cell.lesson = lesson
if self.selected.contains(lesson) {
let index = self.selected.index(of: lesson)
self.selected.remove(at: index!)
} else {
self.selected.append(lesson)
}
等待選擇后,下一步就是處理這些選中的數據了,這里的每條數據,我這里定義了一個model:
enum LessonState {
case invalid, busy, unSelected, selected
}
class Lesson: NSObject {
var time: String?
var state: LessonState = .unSelected
}
只是簡單的給了一個狀態和一個值,記錄狀態和索引.
最后的處理, 我首先想到的是遍歷數組,比較大小,完整的處理邏輯如下:
func btnClick() {
if self.selectedLesson.count > 0 {
self.selectedLesson.removeAll()
}
// 排序
let arr = self.selected.sorted { (first, second) -> Bool in
return Int(first.time!)! < Int(second.time!)!
}
for lesson in arr {
// 輸出排序后的數組
print("\(lesson.time)")
}
// 記錄當前比較的值的索引
var index: Int = 0
// 當索引小于數組長度時,繼續比較
while index < arr.count {
// 取出第一個值
var first = arr[index]
// 取出在大數組中的索引
var index1: Int = self.dataSource.index(of: first)!
// 記錄在大數組中的索引
var range = NSRange()
range.location = index1
// 數組索引+1 ,從下一個開始判斷
index += 1
for i in index..<arr.count {
// 這里又取一次,是為了for循環內的比較
first = arr[i-1]
// 取出下一個元素
let second = arr[i]
// 比較差值
if Int(second.time!)! - Int(first.time!)! == 1{
// 差值為1,代表連續, 大數組索引+1, 小數組索引+1
index1 += 1
index += 1
} else {
// 當不為1時,不連續,跳出循環
break
}
}
// 一次遍歷結束, 創建最終的model
let select = SelectedLesson()
// 計算長度
range.length = index1 - range.location + 1
select.range = range
// 記錄選中的連續區間
self.selectedLesson.append(select)
}
print("******************************")
for selec in self.selectedLesson {
print("\(selec.range) + \(selec.range?.location) + \(selec.range?.length)")
}
}
先將選中的數據根據索引進行從小到大排序,然后,遍歷排序后的數組.
代碼中每一步都有注釋,理解起來應該不是問題,這里就不贅述了.
測試上圖的選擇后輸出為:
Optional("13")
Optional("14")
Optional("15")
Optional("25")
Optional("26")
Optional("27")
Optional("38")
******************************
Optional(__C._NSRange) + Optional(13) + Optional(3)
Optional(__C._NSRange) + Optional(25) + Optional(3)
Optional(__C._NSRange) + Optional(38) + Optional(1)