Ios Swift 3:对象数组的group by和值
我的viewController中有此代码Ios Swift 3:对象数组的group by和值,ios,arrays,swift,Ios,Arrays,Swift,我的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({...}) } var myArray:Array=Array() 对于我在0
var myArray :Array<Data> = Array<Data>()
for i in 0..<mov.count {
myArray.append(Data(...))
}
class Data {
var value :CGFloat
var name :String=""
init({...})
}
var myArray:Array=Array()
对于我在0….. P>首先,你不应该说出你的类<代码>数据< /代码>,因为这是一个基础类的名字。我使用了一个名为MyData
的结构:
struct MyData {
let value: CGFloat
let name: String
}
let myArray: [MyData] = [MyData(value: 10.5, name: "apple"),
MyData(value: 20.0, name: "lemon"),
MyData(value: 15.2, name: "apple"),
MyData(value: 45, name: "")]
您可以使用字典将与每个名称关联的值相加:
var myDictionary = [String: CGFloat]()
for dataItem in myArray {
if dataItem.name.isEmpty {
// ignore entries with empty names
continue
} else if let currentValue = myDictionary[dataItem.name] {
// we have seen this name before, add to its value
myDictionary[dataItem.name] = currentValue + dataItem.value
} else {
// we haven't seen this name, add it to the dictionary
myDictionary[dataItem.name] = dataItem.value
}
}
然后,您可以将字典转换回MyData
对象数组,对它们进行排序并打印它们:
// turn the dictionary back into an array
var resultArray = myDictionary.map { MyData(value: $1, name: $0) }
// sort the array by value
resultArray.sort { $0.value < $1.value }
// print the sorted array
for dataItem in resultArray {
print("\(dataItem.value) \(dataItem.name)")
}
//将字典转换回数组
var resultArray=myDictionary.map{MyData(值:$1,名称:$0)}
//按值对数组排序
resultArray.sort{$0.value<$1.value}
//打印已排序的数组
对于resultArray中的dataItem{
打印(“\(dataItem.value)\(dataItem.name)”)
}
首先,Swift 3中保留了数据
,示例使用名为项的结构
struct Item {
let value : Float
let name : String
}
使用给定的值创建数据数组
let dataArray = [Item(value:10.5, name:"apple"),
Item(value:20.0, name:"lemon"),
Item(value:15.2, name:"apple"),
Item(value:45, name:"")]
以及结果的数组:
var resultArray = [Item]()
现在筛选所有非空名称,并设置一个集合
-每个名称在集合中出现一次:
let allKeys = Set<String>(dataArray.filter({!$0.name.isEmpty}).map{$0.name})
最后,按值desscending对结果数组进行排序:
resultArray.sorted(by: {$0.value < $1.value})
首先更改您的数据类,使字符串成为可选的,这样就更容易处理了。所以现在如果没有名字,它是零。如果需要,您可以将其保留为“”,只需在下面稍作更改:
class Thing {
let name: String?
let value: Double
init(name: String?, value: Double){
self.name = name
self.value = value
}
static func + (lhs: Thing, rhs: Thing) -> Thing? {
if rhs.name != lhs.name {
return nil
} else {
return Thing(name: lhs.name, value: lhs.value + rhs.value)
}
}
}
我给了它一个操作符,这样就可以很容易地添加它们。它返回一个可选值,因此使用时要小心
然后,让我们为充满内容的阵列做一个方便的扩展:
extension Array where Element: Thing {
func grouped() -> [Thing] {
var things = [String: Thing]()
for i in self {
if let name = i.name {
things[name] = (things[name] ?? Thing(name: name, value: 0)) + i
}
}
return things.map{$0.1}.sorted{$0.value > $1.value}
}
}
快速测试一下:
let t1 = Thing(name: "a", value: 1)
let t2 = Thing(name: "b", value: 2)
let t3 = Thing(name: "a", value: 1)
let t4 = Thing(name: "c", value: 3)
let t5 = Thing(name: "b", value: 2)
let t6 = Thing(name: nil, value: 10)
let bb = [t1,t2,t3,t4,t5,t6]
let c = bb.grouped()
//(b,4),(c,3),(a,2)
<>编辑:添加了一个名为NIL的示例,该示例由If让在GROUPER()函数中筛选出来,考虑重新命名数据类,因为基金会包含一个按该名称命名的类。请向我们展示迄今为止您的最佳解决方案,我们可以让您知道您在哪里出错,我正在玩您的答案来理解。我编写了letallkeys=Set(dataArray.filter({!$0.name.isEmpty}))
。我故意没有编写映射{$0.name})
来查看/理解我得到了什么…但是我得到了一个错误,说ambigous reference to member filter。我看了看,但还是解决不了。我做错了什么?没有map
你就得到Set
我得到了。但是现在,如果我只在你的答案中写那么远的话,为什么会出现这样的错误呢?集合
中使用的类型必须符合哈希表
,而简单结构没有。这个错误可能会误导你。歧义是类型不匹配–
Set
被注释,但推断的类型是Set
,或者无法创建集,因为项
不可散列。显然,这是可行的,但它是以非常不快速的方式编写的。:)
extension Array where Element: Thing {
func grouped() -> [Thing] {
var things = [String: Thing]()
for i in self {
if let name = i.name {
things[name] = (things[name] ?? Thing(name: name, value: 0)) + i
}
}
return things.map{$0.1}.sorted{$0.value > $1.value}
}
}
let t1 = Thing(name: "a", value: 1)
let t2 = Thing(name: "b", value: 2)
let t3 = Thing(name: "a", value: 1)
let t4 = Thing(name: "c", value: 3)
let t5 = Thing(name: "b", value: 2)
let t6 = Thing(name: nil, value: 10)
let bb = [t1,t2,t3,t4,t5,t6]
let c = bb.grouped()