按对象类型拆分Swift数组

时间:2017-10-26 06:14:09

标签: arrays swift

我有一个数组,里面有两种自定义对象:

let array = [TaskItem(), TaskItem(), SectionItem(), TaskItem(), TaskItem(), TaskItem(), SectionItem(), TaskItem()]

我想基于其中的SectionItem()对象将其拆分为数组数组,以便每个SectionItem()是每个数组中的第一个项目(第一个数组没有)一节内容):

let newArray = [
  [TaskItem(), TaskItem()],
  [SectionItem(), TaskItem(), TaskItem(), TaskItem()],
  [SectionItem(), TaskItem()]
]

基本上希望它的行为类似于Swift字符串上的components:separatedBy:方法:

let newArray = array.components(separatedBy: SectionItem) //This isn't real

这可以在 Swift 4 吗?

3 个答案:

答案 0 :(得分:0)

这应该是非常直截了当的。您只需要迭代元素并有条件地将它们从Any转换为您的TaskItem类型。如果成功将元素附加到第一个子数组,否则增加结果索引并将新的子数组添加为空结果:

struct TaskItem { }
struct SectionItem { }

let array: [Any] = [TaskItem(), TaskItem(), SectionItem(), TaskItem(), TaskItem(), TaskItem(), SectionItem(), TaskItem()]

var result: [[TaskItem]] = []
result.append([])
var index = 0

for element in array  {
    if let task = element as? TaskItem {
        result[index].append(task)
    } else if !result[index].isEmpty {
        index += 1
        result.append([])
    }
}

print(result) // [[TaskItem, TaskItem], [TaskItem, TaskItem, TaskItem], [TaskItem]]

答案 1 :(得分:0)

试试这个。

let array: [Any] = [TaskItem(), TaskItem(), SectionItem(), TaskItem(), TaskItem(), TaskItem(), SectionItem(), TaskItem()]

var indexes:[Int] = []
for i in 0..<array.count {
    let item = array[i]
    if item is SectionItem {
        indexes.append(i)
    }
}

var result:[[Any]] = []
for i in 0...indexes.count {
    if (i != indexes.count) {
        let index = indexes[i]
        let sindex = i == 0 ? 0 : indexes[i-1]
        result.append(Array(array[sindex..<index]))
    } else {
        let sindex = i == 0 ? 0 : indexes[i-1]
        result.append(Array(array[sindex..<array.count]))
    }
}

//result [[TaskItem(), TaskItem()], [SectionItem(), TaskItem(), TaskItem()], [SectionItem(), TaskItem()]]

答案 2 :(得分:0)

如果你可以放弃拆分中的SectionItem,你可以使用:

array.split { $0 is SectionItem }

如果你没有,并且你可以做一些更丑陋的事情,你可以做这样的事情:

let reduce: [[Item]] = array.reduce([]) { (nextPart, item) -> [[Item]] in
    var next = nextPart
    if item is SectionItem {
        next.append([item])
    } else if var items = next.popLast() {
        items.append(item)
        next.append(items)
    } else {
        next.append([item])
    }
    return next
}