Arrays Swift 5基于对象值对对象数组进行分组和拆分
我有一个排序数组Arrays Swift 5基于对象值对对象数组进行分组和拆分,arrays,swift,Arrays,Swift,我有一个排序数组 let things = [ Thing(activity: "1", name: "value1"), Thing(activity: "1", name: "value2"), Thing(activity: "1", name: "value3"), Thing(activity: "2", name: "value4"), Thing(activity: "2", name: "value5"), Thing(activi
let things = [
Thing(activity: "1", name: "value1"),
Thing(activity: "1", name: "value2"),
Thing(activity: "1", name: "value3"),
Thing(activity: "2", name: "value4"),
Thing(activity: "2", name: "value5"),
Thing(activity: "3", name: "value6"),
Thing(activity: "3", name: "value7"),
Thing(activity: "1", name: "value8"),
Thing(activity: "1", name: "value9"),
Thing(activity: "1", name: "value10")
]
我希望在活动值更改时生成拆分的数组数组,如下所示
[[Thing(activity: "1", name: "value1"),
Thing(activity: "1", name: "value2"),
Thing(activity: "1", name: "value3")],
[Thing(activity: "2", name: "value4"),
Thing(activity: "2", name: "value5")],
[Thing(activity: "3", name: "value6"),
Thing(activity: "3", name: "value7")],
[Thing(activity: "1", name: "value8"),
Thing(activity: "1", name: "value9"),
Thing(activity: "1", name: "value10")]]
正如@matt在评论中已经提到的,您可以使用集合方法reduceinto:通过检查最后一个数组的最后一个元素的活动是否等于当前元素活动来对元素进行分组,如果是这样,只需将新元素附加到最后一个数组中,否则将带有单个元素的新数组附加到外部数组中:
struct Thing {
let activity, name: String
}
一般的解决办法是:
extension Sequence {
func grouped<T: Equatable>(by block: (Element) throws -> T) rethrows -> [[Element]] {
return try reduce(into: []) { result, element in
if let lastElement = result.last?.last, try block(lastElement) == block(element) {
result[result.index(before: result.endIndex)].append(element)
} else {
result.append([element])
}
}
}
}
一个不那么优雅但稍微高效的解决方案是:
extension Sequence {
func grouped<T: Equatable>(by block: (Element) throws -> T) rethrows -> [[Element]] {
var results: [[Element]] = []
var lastValue: T?
var index = results.endIndex
for element in self {
let value = try block(element)
if let lastValue = lastValue, lastValue == value {
results[index].append(element)
} else {
results.append([element])
index = results.index(before: results.endIndex)
lastValue = value
}
}
return results
}
}
使用reduceinto:。效果很好!。谢谢,回答得好。我将使用利奥的答案,因为它立即解决了我的问题。非常感谢。
extension Sequence {
func grouped<T: Equatable>(by block: (Element) throws -> T) rethrows -> [[Element]] {
return try reduce(into: []) { result, element in
if let lastElement = result.last?.last, try block(lastElement) == block(element) {
result[result.index(before: result.endIndex)].append(element)
} else {
result.append([element])
}
}
}
}
let results = things.grouped { $0.activity }
extension Sequence {
func grouped<T: Equatable>(by block: (Element) throws -> T) rethrows -> [[Element]] {
var results: [[Element]] = []
var lastValue: T?
var index = results.endIndex
for element in self {
let value = try block(element)
if let lastValue = lastValue, lastValue == value {
results[index].append(element)
} else {
results.append([element])
index = results.index(before: results.endIndex)
lastValue = value
}
}
return results
}
}