简体   繁体   English

将两个不同类型的数组排序为一个

[英]Sort Two Arrays of Different Types into One

I have two arrays, they are of two different objects, and both contain an ID field. 我有两个数组,它们是两个不同的对象,并且都包含一个ID字段。 What I need to do is display them in order in a table view controller. 我需要做的是在表视图控制器中按顺序显示它们。 They share the same basic info, Size and ID, and those are the only pieces of data displayed, in addition to the type of object it is. 它们共享相同的基本信息,大小和ID,除了显示的是对象类型之外,它们是唯一显示的数据。 When the user selects a cell then it moves to a new view that displays the finer details of the object. 当用户选择一个单元格时,它将移动到一个新视图,该视图显示该对象的详细信息。

Right now, I have two sections in the table, one for TypeA, and the other for TypeB. 现在,表中有两个部分,一个部分用于TypeA,另一部分用于TypeB。 They sort through all of the items in their respective list, but are out of order for when the item was made. 他们对各自列表中的所有项目进行排序,但在制造项目时却无序。 So it looks like: 所以看起来像:

TypeA
  ID 1
  ID 2
  ID 5
  ID 6
TypeB
  ID 3
  ID 4
  ID 7

What I need is for it to sort them all into 1 section, and still open the detail view when selected. 我需要的是将它们全部分类为1个部分,并在选择时仍打开详细视图。

Thoughts 思考

I could put them all into an AnyObject dictionary and when looking at individual items determine if they are of one object type or the other. 我可以将它们全部放入AnyObject字典中,并在查看单个项目时确定它们是否属于一种对象类型或另一种。 I feel like that would work, but how would I go about sorting that correctly? 我觉得这行得通,但是我该如何正确地对其进行排序呢?

Put all common properties into a protocol, the build and sort an array of that common protocol: 将所有通用属性放入协议中,构建并排序该通用协议的数组:

protocol HasID {
    var id: Int { get }
}

class TypeA : HasID, CustomStringConvertible {
    var id: Int

    init(_ id: Int) {
        self.id = id
    }

    var description : String {
        return ("TypeA(\(self.id))")
    }
}

class TypeB : HasID, CustomStringConvertible {
    var id: Int

    init(_ id: Int) {
        self.id = id
    }

    var description : String {
        return ("TypeB(\(self.id))")
    }
}

let typeA = [TypeA(1), TypeA(2), TypeA(5), TypeA(6)]
let typeB = [TypeB(3), TypeB(4), TypeB(7)]
let result: [HasID] = (typeA + typeB).sorted { $0.id < $1.id }

print(result)
 [TypeA(1), TypeA(2), TypeB(3), TypeB(4), TypeA(5), TypeA(6), TypeB(7)] 

Alternatively to Zoff Dino answer if you do not want to burden TypeA and TypeB classes with HasID protocol then you can define extension to these classes in your view controller: 如果您不想使用HasID协议负担TypeATypeB类,则可以选择Zoff Dino答案,然后可以在视图控制器中为这些类定义扩展:

class TypeA {
    var ID: Int

    init(_ id: Int) {
        self.ID = id
    }
}

class TypeB {
    var ID: Int

    init(_ id: Int) {
        self.ID = id
    }
}

protocol HasID {
    var ID: Int { get }
}

// place this in your view controller

extension TypeA: HasID {
}

extension TypeB: HasID {
}

var arrayA = [TypeA(1), TypeA(3), TypeA(5)]
var arrayB = [TypeB(2), TypeB(4)]

let sortedArray = (arrayA.map { $0 as HasID } + arrayB.map { $0 as HasID })
                      .sort { $0.ID < $1.ID }

You can do this like so: 您可以这样做:

class TypeA {
    var ID: Int

    init(_ id: Int) {
        self.ID = id
    }
}

class TypeB {
    var ID: Int

    init(_ id: Int) {
        self.ID = id
    }
}

struct Wrap {
    var ID: Int {
        return a?.ID ?? b?.ID ?? 0
    }
    let a: TypeA?
    let b: TypeB?
}

var arrayA = [TypeA(1), TypeA(3), TypeA(5)]
var arrayB = [TypeB(2), TypeB(4)]

let sortedArray = (arrayA.map { Wrap(a: $0, b: nil) } + arrayB.map { Wrap(a: nil, b: $0)})
                      .sorted { $0.ID < $1.ID }

When row is selected you can determine object with: 选择行后,您可以通过以下方式确定对象:

if let a = sortedArray[index].a {
    // TypeA row selected
} else if let b = sortedArray[index].b {
    // TypeB row selected
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM