如何创建一个函数来搜索 ID、定位和更改此记录的一个字段?
How can I create a function to search for an ID, locate and change one field of this record?
型号:
enum TaskType: Int, Codable {
case upcoming = 0
case inProgress
case testing
case completed
var title: String {
switch self {
case .upcoming:
return "Upcoming"
case .inProgress:
return "In Progress"
case .testing:
return "Testing"
case .completed:
return "Completed"
}
}
}
struct TasksModel: Encodable, Decodable {
var upcomingArray: [TaskInfo]
var inProgressArray: [TaskInfo]
var testingArray: [TaskInfo]
var completedArray: [TaskInfo]
}
struct TaskInfo: Codable, Equatable, Identifiable {
var id: String
var title: String
var description: String
var taskStatus: TaskType
var taskDate = Date()
}
虚拟机:
class HomeVM: ObservableObject {
@Published var tasksArray: TasksModel
self.tasksArray = TasksModel.init(upcomingArray: [], inProgressArray: [], testingArray: [], completedArray: [])
}
现在我可以找到具有接收到的 taskID 的记录并更改 taskStatus,我还需要将记录从 comcomingArray 移动到 inProgressArray。这就是我正在尝试的:
func inProgressSetTask(taskID: String) {
@StateObject var viewModel = HomeVM()
if let index = viewModel.tasksArray.upcomingArray.firstIndex(where: {[=12=].id == taskID}) {
// Update task status
viewModel.tasksArray.upcomingArray[index].taskStatus = .inProgress
// Need to remove from upcomingArray and append into inProgressArray
viewModel.tasksArray.upcomingArray.remove(at: index)
var lastIndex = viewModel.tasksArray.inProgressArray.last
viewModel.tasksArray.inProgressArray[lastIndex].append()
viewModel.save()
// End
} else {
…
更新上面的 taskStatus 工作正常,但从一个数组移除到另一个数组则不行。
上面的代码将在 else 之后对每个数组重复。感谢任何帮助。
您正试图将 String
与 TaskInfo
进行比较,因为 inProgressArray
的元素属于 TaskInfo
类型。您需要做的是钻入数组并到达 .id
。这很容易做到。在 .first(where:)
中,您只需传递 [=17=].id == taskID
.
的闭包
if let index = viewModel.tasksArray.inProgressArray.first(where: { [=10=].id == taskID } ) {
您可以尝试以下示例代码来实现您想要的:
(请注意,您应该在 func inProgressSetTask(taskID: String) {...}
之外添加 @StateObject var viewModel = HomeVM()
或作为参数传入)
EDIT-1:将包含所有数组的函数移动到 HomeVM
并假设 id
是唯一的。
func inProgressSetTask(taskID: String) {
print("InProgress Set ID# \(taskID)")
// with index, using `firstIndex`
if let index = viewModel.tasksArray.inProgressArray.firstIndex(where: {[=10=].id == taskID}) {
// do something with the index
viewModel.tasksArray.inProgressArray[index].title = "xxx"
}
// with TaskInfo, using `first`
if var taskInfo = viewModel.tasksArray.inProgressArray.first(where: {[=10=].id == taskID}) {
// do something with the taskInfo
taskInfo.title = "xxx"
}
}
对于TaskInfo的所有数组,使用HomeVM
中的函数setTaskFromAll(...)
。例如:viewModel.setTaskFromAll(taskID: "1")
class HomeVM: ObservableObject {
@Published var tasksArray: TasksModel = TasksModel.init(upcomingArray: [], inProgressArray: [], testingArray: [], completedArray: [])
func setTaskFromAll(taskID: String) {
if let index = tasksArray.inProgressArray.firstIndex(where: {[=11=].id == taskID}) {
tasksArray.inProgressArray[index].title = "inProgress"
} else {
if let index = tasksArray.completedArray.firstIndex(where: {[=11=].id == taskID}) {
tasksArray.completedArray[index].title = "completed"
} else {
if let index = tasksArray.testingArray.firstIndex(where: {[=11=].id == taskID}) {
tasksArray.testingArray[index].title = "testing"
} else {
if let index = tasksArray.upcomingArray.firstIndex(where: {[=11=].id == taskID}) {
tasksArray.upcomingArray[index].title = "upcoming"
}
}
}
}
}
}
编辑-2:
但是,由于您已经在 TaskInfo
结构中拥有每个数组的“TaskType”,为什么不删除 TasksModel
并在 HomeVM
中使用 TaskInfo
的单个数组。像这样:
class HomeVM: ObservableObject {
@Published var tasksArray: [TaskInfo] = [
TaskInfo(id: "1", title: "title1", description: "description1", taskStatus: .upcoming),
TaskInfo(id: "2", title: "title2", description: "description2", taskStatus: .inProgress)
// ....
]
func setTask(taskID: String, to taskType: TaskType) {
if let index = tasksArray.firstIndex(where: {[=12=].id == taskID}) {
tasksArray[index].taskStatus = taskType
}
}
func getAllTaskInfo(_ oftype: TaskType) -> [TaskInfo] {
return tasksArray.filter{[=12=].taskStatus == oftype}
}
}
并像这样使用它:viewModel.setTask(taskID: "1", to: .testing)
和 viewModel.getAllTaskInfo(.inProgress)
EDIT-3:要从一个数组中删除并附加到另一个数组中,使用您的 TasksModel
方案,请使用:
class HomeVM: ObservableObject {
@Published var tasksArray: TasksModel = TasksModel(upcomingArray: [
TaskInfo(id: "1", title: "title1", description: "description1", taskStatus: .upcoming),
TaskInfo(id: "2", title: "title2", description: "description2", taskStatus: .upcoming)
], inProgressArray: [
TaskInfo(id: "3", title: "title3", description: "description3", taskStatus: .inProgress),
TaskInfo(id: "4", title: "title4", description: "description4", taskStatus: .inProgress)
], testingArray: [], completedArray: [])
func inProgressSetTask(taskID: String) {
if let index = tasksArray.upcomingArray.firstIndex(where: {[=13=].id == taskID}) {
// update task status
tasksArray.upcomingArray[index].taskStatus = .inProgress
// get the upcomingArray taskInfo
let taskInfo = tasksArray.upcomingArray[index]
// remove from upcomingArray
tasksArray.upcomingArray.remove(at: index)
// append to inProgressArray
tasksArray.inProgressArray.append(taskInfo)
} else {
// ...
}
}
}
这样使用:viewModel.inProgressSetTask(taskID: "1")
如你所见,你在EDIT-2
中better-off,无缘无故在EDIT-3
中repeating/duplicating。不需要为不同的 TaskType
使用单独的数组,您已经在 TaskInfo
var taskStatus: TaskType
中获得了此信息。使用 EDIT-2
,使用 viewModel.getAllTaskInfo(.inProgress)
获取特定类型的所有 TaskInfo
,就像使用单独的数组一样。
型号:
enum TaskType: Int, Codable {
case upcoming = 0
case inProgress
case testing
case completed
var title: String {
switch self {
case .upcoming:
return "Upcoming"
case .inProgress:
return "In Progress"
case .testing:
return "Testing"
case .completed:
return "Completed"
}
}
}
struct TasksModel: Encodable, Decodable {
var upcomingArray: [TaskInfo]
var inProgressArray: [TaskInfo]
var testingArray: [TaskInfo]
var completedArray: [TaskInfo]
}
struct TaskInfo: Codable, Equatable, Identifiable {
var id: String
var title: String
var description: String
var taskStatus: TaskType
var taskDate = Date()
}
虚拟机:
class HomeVM: ObservableObject {
@Published var tasksArray: TasksModel
self.tasksArray = TasksModel.init(upcomingArray: [], inProgressArray: [], testingArray: [], completedArray: [])
}
现在我可以找到具有接收到的 taskID 的记录并更改 taskStatus,我还需要将记录从 comcomingArray 移动到 inProgressArray。这就是我正在尝试的:
func inProgressSetTask(taskID: String) {
@StateObject var viewModel = HomeVM()
if let index = viewModel.tasksArray.upcomingArray.firstIndex(where: {[=12=].id == taskID}) {
// Update task status
viewModel.tasksArray.upcomingArray[index].taskStatus = .inProgress
// Need to remove from upcomingArray and append into inProgressArray
viewModel.tasksArray.upcomingArray.remove(at: index)
var lastIndex = viewModel.tasksArray.inProgressArray.last
viewModel.tasksArray.inProgressArray[lastIndex].append()
viewModel.save()
// End
} else {
…
更新上面的 taskStatus 工作正常,但从一个数组移除到另一个数组则不行。
上面的代码将在 else 之后对每个数组重复。感谢任何帮助。
您正试图将 String
与 TaskInfo
进行比较,因为 inProgressArray
的元素属于 TaskInfo
类型。您需要做的是钻入数组并到达 .id
。这很容易做到。在 .first(where:)
中,您只需传递 [=17=].id == taskID
.
if let index = viewModel.tasksArray.inProgressArray.first(where: { [=10=].id == taskID } ) {
您可以尝试以下示例代码来实现您想要的:
(请注意,您应该在 func inProgressSetTask(taskID: String) {...}
之外添加 @StateObject var viewModel = HomeVM()
或作为参数传入)
EDIT-1:将包含所有数组的函数移动到 HomeVM
并假设 id
是唯一的。
func inProgressSetTask(taskID: String) {
print("InProgress Set ID# \(taskID)")
// with index, using `firstIndex`
if let index = viewModel.tasksArray.inProgressArray.firstIndex(where: {[=10=].id == taskID}) {
// do something with the index
viewModel.tasksArray.inProgressArray[index].title = "xxx"
}
// with TaskInfo, using `first`
if var taskInfo = viewModel.tasksArray.inProgressArray.first(where: {[=10=].id == taskID}) {
// do something with the taskInfo
taskInfo.title = "xxx"
}
}
对于TaskInfo的所有数组,使用HomeVM
中的函数setTaskFromAll(...)
。例如:viewModel.setTaskFromAll(taskID: "1")
class HomeVM: ObservableObject {
@Published var tasksArray: TasksModel = TasksModel.init(upcomingArray: [], inProgressArray: [], testingArray: [], completedArray: [])
func setTaskFromAll(taskID: String) {
if let index = tasksArray.inProgressArray.firstIndex(where: {[=11=].id == taskID}) {
tasksArray.inProgressArray[index].title = "inProgress"
} else {
if let index = tasksArray.completedArray.firstIndex(where: {[=11=].id == taskID}) {
tasksArray.completedArray[index].title = "completed"
} else {
if let index = tasksArray.testingArray.firstIndex(where: {[=11=].id == taskID}) {
tasksArray.testingArray[index].title = "testing"
} else {
if let index = tasksArray.upcomingArray.firstIndex(where: {[=11=].id == taskID}) {
tasksArray.upcomingArray[index].title = "upcoming"
}
}
}
}
}
}
编辑-2:
但是,由于您已经在 TaskInfo
结构中拥有每个数组的“TaskType”,为什么不删除 TasksModel
并在 HomeVM
中使用 TaskInfo
的单个数组。像这样:
class HomeVM: ObservableObject {
@Published var tasksArray: [TaskInfo] = [
TaskInfo(id: "1", title: "title1", description: "description1", taskStatus: .upcoming),
TaskInfo(id: "2", title: "title2", description: "description2", taskStatus: .inProgress)
// ....
]
func setTask(taskID: String, to taskType: TaskType) {
if let index = tasksArray.firstIndex(where: {[=12=].id == taskID}) {
tasksArray[index].taskStatus = taskType
}
}
func getAllTaskInfo(_ oftype: TaskType) -> [TaskInfo] {
return tasksArray.filter{[=12=].taskStatus == oftype}
}
}
并像这样使用它:viewModel.setTask(taskID: "1", to: .testing)
和 viewModel.getAllTaskInfo(.inProgress)
EDIT-3:要从一个数组中删除并附加到另一个数组中,使用您的 TasksModel
方案,请使用:
class HomeVM: ObservableObject {
@Published var tasksArray: TasksModel = TasksModel(upcomingArray: [
TaskInfo(id: "1", title: "title1", description: "description1", taskStatus: .upcoming),
TaskInfo(id: "2", title: "title2", description: "description2", taskStatus: .upcoming)
], inProgressArray: [
TaskInfo(id: "3", title: "title3", description: "description3", taskStatus: .inProgress),
TaskInfo(id: "4", title: "title4", description: "description4", taskStatus: .inProgress)
], testingArray: [], completedArray: [])
func inProgressSetTask(taskID: String) {
if let index = tasksArray.upcomingArray.firstIndex(where: {[=13=].id == taskID}) {
// update task status
tasksArray.upcomingArray[index].taskStatus = .inProgress
// get the upcomingArray taskInfo
let taskInfo = tasksArray.upcomingArray[index]
// remove from upcomingArray
tasksArray.upcomingArray.remove(at: index)
// append to inProgressArray
tasksArray.inProgressArray.append(taskInfo)
} else {
// ...
}
}
}
这样使用:viewModel.inProgressSetTask(taskID: "1")
如你所见,你在EDIT-2
中better-off,无缘无故在EDIT-3
中repeating/duplicating。不需要为不同的 TaskType
使用单独的数组,您已经在 TaskInfo
var taskStatus: TaskType
中获得了此信息。使用 EDIT-2
,使用 viewModel.getAllTaskInfo(.inProgress)
获取特定类型的所有 TaskInfo
,就像使用单独的数组一样。