【问题标题】:Sort Two Arrays of Different Types into One将两个不同类型的数组归为一个
【发布时间】:2015-10-06 16:56:56
【问题描述】:

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

现在,我的表格中有两个部分,一个用于 TypeA,另一个用于 TypeB。他们对各自列表中的所有项目进行排序,但在项目的制作时间是无序的。所以它看起来像:

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

我需要将它们全部归为 1 个部分,并在选择时仍打开详细视图。

想法

我可以将它们全部放入 AnyObject 字典中,并在查看单个项目时确定它们是否属于一种对象类型。我觉得这样可行,但我该如何正确排序呢?

【问题讨论】:

  • 最好在swift 2中使用间接枚举来达到这个目的

标签: ios arrays swift sorting object


【解决方案1】:

将所有通用属性放入一个协议中,构建并排序该通用协议的数组:

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)] 

【讨论】:

    【解决方案2】:

    如果您不想使用 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 }
    

    【讨论】:

      【解决方案3】:

      你可以这样做:

      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 }
      

      选择行时,可以使用以下内容确定对象:

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

      【讨论】:

      • 感谢您的回复。这就是我使用你的建议时得到的 呼啦:1 呼啦:2 呼啦:3 呼啦:4 呼啦:7 呼啦:10 呼啦:15 线性:1 线性:2 线性:8 线性:9 线性:11 线性: 12 linear: 13 linear: 14 其中hula和linear分别是TypeA和TypeB。知道发生了什么吗?
      • @CodyHarness 你错误地采用了我的解决方案。如果您将我的代码复制并粘贴到 Playground 中,您会看到它可以正常工作。
      • @CodyHarness 你确定你的代码包含.sort { $0.ID &lt; $1.ID }吗?
      • 在早期版本的 Swift 中存在一个错误,导致数组无法正确排序。如果您在仔细检查代码后仍未看到数组已排序,请尝试更新您的 Xcode/SDK 版本。
      • @cc。我发现了我的错误。我是根据对象中错误的 id 值进行排序的。它现在正在工作。
      猜你喜欢
      • 2021-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多