使用Swift中的高阶函数更新数组值

时间:2017-07-25 09:11:05

标签: ios arrays swift closures

我正在努力使用新的map,flatMap,filter,reduce和zip函数。考虑以下: 你有两个数组,A和B,包含不同的对象。对于A中的每个对象,您需要在B中找到相应的对象(通过它们的id属性),并从B更新对象的一些属性。这可以用旧的方式完成,使用两个循环,如下所示:

private func update(statuses: [JobStatus], forJobs jobs: [JobBookPayload]) {
    for jobStatus in statuses {
        for job in jobs {
            if jobStatus.jobId == job.jobId {
                job.status = jobStatus.status!
                job.option = jobStatus.option!
            }
        }
    }
}

可以使用新功能完成,使代码更“Swifty”并提高可读性吗?

3 个答案:

答案 0 :(得分:2)

我想,既然您正在使用课程,那么您实际上并不想从旧课程中创建新对象。我相信这可以使用activeWorksheet.Rows.RowHeightmap方法来实现:

first

使用@discardableResult func update(statuses: [JobStatus], forJobs jobs: [JobBookPayload]) -> [JobBookPayload] { return jobs.map({ (payload) -> JobBookPayload in if let status = statuses.first(where: { payload.jobId == $0.jobId }) { payload.status = status.status payload.option = status.option } return payload }) } 将允许您使用此函数并忽略生成的数组 - 无论如何,初始数组中的对象都会发生变异。

答案 1 :(得分:1)

for .. in .. { if conditional { ... } }

替换for .. in .. where conditional { ... }

您可以通过在内部where循环中引入for子句来替换其正文的单个if语句,从而进行次要的重新分解:

private func update(statuses: [JobStatus], forJobs jobs: [JobBookPayload]) {
    for jobStatus in statuses {
        for job in jobs where jobStatus.jobId == job.jobId {
            job.status = jobStatus.status!
            job.option = jobStatus.option!
        }
    }
}

答案 2 :(得分:0)

“新”(功能)方式的想法是从前一个创建一个新对象:

private func update(statuses: [JobStatus], for jobs: [JobBookPayload]) -> [JobBookPayload] {
    return jobs.reduce([]) { newJobs, job in
        return newJobs + statuses.flatMap { status in
            return status.jobId == job.jobId ?
                //Construct a new object
                JobBookPayload(status: status.status, option: status.option) : nil
        }
    }
}

假设有一个status对象与job对应:

private func update(statuses: [JobStatus], for jobs: [JobBookPayload]) -> [JobBookPayload] {
    return jobs.reduce([]) { newJobs, job in
        return newJobs + statuses.lazy.filter { $0.jobId == job.jobId }.first.flatMap { 
            JobBookPayload(status: $0.status, option: $0.option) // Construct the object
        }
    }
}

避免reduce

private func update(statuses: [JobStatus], for jobs: [JobBookPayload]) -> [JobBookPayload] {
    return jobs.flatMap { job in
        return statuses.flatMap { status in
            return status.jobId == job.jobId ?
                //Construct a new object
                JobBookPayload(status: status.status, option: status.option) : nil
        }.last
    }
}