在结构数组上执行数组函数

时间:2016-09-25 02:05:18

标签: arrays swift function struct swift2

让我们说我有以下结构:

struct LogInfo {
    var logNumber: Int
    var species: String
    var diameter: Float
    var formClass: Int
    var numLogs: Float
    var boardFootage: Double
}

并填充以下内容:

var logInfoArray = [LogInfo]()

logInfoArray.append(LogInfo(logNumber: 1, species: "Spruce", diameter: 18.0, formClass: 78, numLogs: 1.5, boardFootage: 110.0))
logInfoArray.append(LogInfo(logNumber: 2, species: "Spruce", diameter: 17.0, formClass: 78, numLogs: 1.0, boardFootage: 90.0))
logInfoArray.append(LogInfo(logNumber: 3, species: "Pine", diameter: 18.0, formClass: 78, numLogs: 1.5, boardFootage: 89.0))
logInfoArray.append(LogInfo(logNumber: 4, species: "Pine", diameter: 21.0, formClass: 78, numLogs: 1.0, boardFootage: 120.0))
logInfoArray.append(LogInfo(logNumber: 5, species: "Pine", diameter: 19.0, formClass: 78, numLogs: 1.5, boardFootage: 200.0))
logInfoArray.append(LogInfo(logNumber: 6, species: "Oak", diameter: 22.0, formClass: 78, numLogs: 2, boardFootage: 180.0))

我如何在这些条目上执行某些数组函数?

例如 - 我想弄清楚阵列中有多少独特的物种,最后得到一个包含每个物种的新阵列。

i.e. var speciesArray = ["Spruce", "Pine", "Oak"]

我还希望能够在考虑到这些时进行一些计算。比如,计算所有具有" Pine"的条目的总板数值。作为物种。

有没有人有关于如何解决这个问题的一些提示?

提前谢谢!

1 个答案:

答案 0 :(得分:1)

要查找唯一种类,请使用map创建speciesSet的数组以查找唯一的种类,并使用Array将结果转换回一个数组:

let unique = Array(Set(logInfoArray.map { $0.species }))
print(unique)  // ["Oak", "Pine", "Spruce"]

要查找Pines的总板数,请使用filter选择Pines,然后使用reduce累计松树的电路板素材:

let totalBoardFootage = logInfoArray.filter { $0.species == "Pine" }.reduce(0) { $0 + $1.boardFootage }
print(totalBoardFootage)  // 409.0

为了更清楚,让我们为闭包中的参数命名。

filter的工作原理是创建一个只包含原始数组中那些导致闭包返回true的项的新数组。在上面的示例中,filter仅创建一个新数组,其中只包含"Pine"种类的项目。

reduce通过调用数组中每个项的闭包来工作。在每次传递中,当前运行总计作为第一个参数(0中的reduce(0)是初始总数)传入,并且数组中的当前项目作为第二个项目传入。闭包返回的值是新的运行总计,它将传递给数组中下一个项的闭包。

let totalBoardFootage = logInfoArray.filter { item in item.species == "Pine" }.reduce(0) { (total, item) in total + item.boardFootage }

要查找所有项目的总板数,只需省略过滤掉松树的部分:

let totalBoardFootageForAllSpecies = logInfoArray.reduce(0) { (total, item) in total + item.boardFootage }