我的 viewController 中有这段代码
var myArray :Array<Data> = Array<Data>()
for i in 0..<mov.count {
myArray.append(Data(...))
}
class Data {
var value :CGFloat
var name :String=""
init({...})
}
Run Code Online (Sandbox Code Playgroud)
我输入的数据如下:
一旦我循环,我想返回一个新数组:
基于输入的预期结果:
我写了很多行代码,太混乱了,无法发布。我会找到更简单的方法,有人对此有想法吗?
首先Data是 Swift 3 中保留的,该示例使用名为 的结构体Item。
struct Item {
let value : Float
let name : String
}
Run Code Online (Sandbox Code Playgroud)
使用给定值创建数据数组
let dataArray = [Item(value:10.5, name:"apple"),
Item(value:20.0, name:"lemon"),
Item(value:15.2, name:"apple"),
Item(value:45, name:"")]
Run Code Online (Sandbox Code Playgroud)
以及结果的数组:
var resultArray = [Item]()
Run Code Online (Sandbox Code Playgroud)
现在过滤所有不为空的名称并创建一个Set- 每个名称在集合中出现一次:
let allKeys = Set<String>(dataArray.filter({!$0.name.isEmpty}).map{$0.name})
Run Code Online (Sandbox Code Playgroud)
遍历键,过滤所有具有dataArray相同名称的项目,对值求和并创建一个Item具有总价值的新项目:
for key in allKeys {
let sum = dataArray.filter({$0.name == key}).map({$0.value}).reduce(0, +)
resultArray.append(Item(value:sum, name:key))
}
Run Code Online (Sandbox Code Playgroud)
最后按值降序对结果数组进行排序:
resultArray.sorted(by: {$0.value < $1.value})
Run Code Online (Sandbox Code Playgroud)
---
编辑:
Swift 4 中引入了一个更有效的 API,可以通过谓词对数组进行分组,Dictionary(grouping:by:
var grouped = Dictionary(grouping: dataArray, by:{$0.name})
grouped.removeValue(forKey: "") // remove the items with the empty name
resultArray = grouped.keys.map { (key) -> Item in
let value = grouped[key]!
return Item(value: value.map{$0.value}.reduce(0.0, +), name: key)
}.sorted{$0.value < $1.value}
print(resultArray)
Run Code Online (Sandbox Code Playgroud)