Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays Swift 5基于对象值对对象数组进行分组和拆分_Arrays_Swift - Fatal编程技术网

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
    } 
}