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

时间:2022-10-11 12:15:46

I have two arrays, they are of two different objects, and both contain an ID field. 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. When the user selects a cell then it moves to a new view that displays the finer details of the object.

我有两个数组,它们有两个不同的对象,都包含一个ID字段。我需要做的是在表视图控制器中按顺序显示它们。它们共享相同的基本信息,大小和ID,除了它们的对象类型之外,它们是显示的唯一数据。当用户选择单元格时,它将移动到显示对象的更精细细节的新视图。

Right now, I have two sections in the table, one for TypeA, and the other for 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,另一个用于TypeB。他们对各自列表中的所有项目进行排序,但在项目制作时却无序。所以它看起来像:

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. I feel like that would work, but how would I go about sorting that correctly?

我可以将它们全部放入AnyObject字典中,当查看单个项目时,确定它们是一种对象类型还是另一种。我觉得这样可行,但我怎样才能正确排序呢?

3 个解决方案

#1


3  

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)})
                      .sort { $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
}

#2


3  

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 = (typeA.map { $0 as HasID } + typeB.map { $0 as HasID })
                .sort { $0.id < $1.id }

print(result)

#3


0  

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协议加载TypeA和TypeB类,那么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 }

#1


3  

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)})
                      .sort { $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
}

#2


3  

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 = (typeA.map { $0 as HasID } + typeB.map { $0 as HasID })
                .sort { $0.id < $1.id }

print(result)

#3


0  

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协议加载TypeA和TypeB类,那么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 }