【问题标题】:Sorting Custom Object Array in swift with different parameter使用不同的参数快速排序自定义对象数组
【发布时间】:2016-02-22 13:28:56
【问题描述】:

我有一个自定义类的数组

class GameInfo {
var gameStatus :String
var country : String
var isSelected : Bool
}

这里,gameStatus 可能是“*”/“1-0”/“1/2-1/2”

我想先按isSelected 对数组进行排序,然后是gameStatus,然后是country

我尝试了sortInPlace,但对我不起作用。

假设这是我的数组

let list = [
    GameInfo(gameStatus: "*", country: "Italy", isSelected: true),
    GameInfo(gameStatus: "1/2-1/2", country: "France", isSelected: true),
    GameInfo(gameStatus: "1-0", country: "Italy", isSelected: false),
    GameInfo(gameStatus: "*", country: "Germany", isSelected: false),
    GameInfo(gameStatus: "0-1", country: "Italy", isSelected: true),
 GameInfo(gameStatus: "1/2-1/2", country: "France", isSelected: false),
    GameInfo(gameStatus: "*", country: "UK", isSelected: false)
]

如果在选定的游戏中有任何现场游戏应该在顶部,即使在与我的国家/地区相关的任何游戏中该游戏在顶部

假设我的国家是意大利,那么数组的排序顺序是

     GameInfo(gameStatus: "*", country: "Italy", isSelected: true),
    GameInfo(gameStatus: "0-1", country: "Italy", isSelected: true),
    GameInfo(gameStatus: "1/2-1/2", country: "France", isSelected: true),
     GameInfo(gameStatus: "*", country: "Germany", isSelected: false),
    GameInfo(gameStatus: "*", country: "UK", isSelected: false)
    GameInfo(gameStatus: "1-0", country: "Italy", isSelected: false),
   GameInfo(gameStatus: "1/2-1/2", country: "France", isSelected: false),

【问题讨论】:

  • 我们针对您的问题发布了几个答案。请提供反馈,如果答案确实解决了您的问题,请接受。
  • 如我所愿,它不能解决我的问题。我必须通过使用许多数组和 arrayfiltermethod 来管理这个:)

标签: ios arrays swift sorting


【解决方案1】:

解决方案 1

您可以将自己的逻辑写入传递给sort 的闭包中。

所以给定这个类

class GameInfo {
    var gameStatus: String
    var country: String
    var isSelected: Bool

    init(gameStatus: String, country: String, isSelected: Bool) {
        self.gameStatus = gameStatus
        self.country = country
        self.isSelected = isSelected
    }
}

还有这份清单

let list = [
    GameInfo(gameStatus: "A", country: "Italy", isSelected: true),
    GameInfo(gameStatus: "A", country: "France", isSelected: true),
    GameInfo(gameStatus: "B", country: "UK", isSelected: true),
    GameInfo(gameStatus: "B", country: "Germany", isSelected: false),
    GameInfo(gameStatus: "A", country: "Italy", isSelected: true),
    GameInfo(gameStatus: "B", country: "UK", isSelected: false)
]

您可以通过这种方式创建排序列表

let sorted = list.sort {
    guard $0.isSelected == $1.isSelected else { return $0.isSelected }
    guard $0.gameStatus == $1.gameStatus else { return $0.gameStatus < $1.gameStatus }
    guard $0.country == $1.country else { return $0.country < $1.country }
    return true
}

解决方案 2

您可以使您的GameInfo 类符合Comparable

class GameInfo: Comparable {
    var gameStatus: String
    var country: String
    var isSelected: Bool

    init(gameStatus: String, country: String, isSelected: Bool) {
        self.gameStatus = gameStatus
        self.country = country
        self.isSelected = isSelected
    }
}

func ==(left: GameInfo, right: GameInfo) -> Bool {
    return
        left.isSelected == right.isSelected &&
        left.gameStatus == right.gameStatus &&
        left.country == right.country
}

func <(left: GameInfo, right: GameInfo) -> Bool {
    guard left.isSelected == right.isSelected else { return left.isSelected }
    guard left.gameStatus == right.gameStatus else { return left.gameStatus < right.gameStatus }
    guard left.country == right.country else { return left.country < right.country }
    return true
}

现在您可以直接调用 sort 而无需其他参数。

let sorted = list.sort()

【讨论】:

    【解决方案2】:

    试试这个(旧式 Objective-C 数组排序):

    let sortedArray = (yourArray as NSArray).sortedArrayUsingDescriptors([
      NSSortDescriptor(key: "isSelected", ascending: true),
      NSSortDescriptor(key: "gameStatus", ascending: true),
      NSSortDescriptor(key: "country", ascending: true)
    ]) as! [GameInfo]
    

    在这种情况下,您的 GameInfo 类必须是这样的。这不是解决问题的简单方法,仅供参考。使用 NSSortDescriptors 对多个条件进行排序非常容易和自然,但仅适用于 Objective-C,除非我们的 swift 类在某些条件下(实现)。

    class GameInfo : NSObject {
        var gameStatus: String?
        var country: String?
        var isSelected: Bool
    
        init(gameStatus: String, country: String, isSelected: Bool) {
            self.gameStatus = gameStatus
            self.country = country
            self.isSelected = isSelected
        }
    
        override func valueForKey(key: String) -> AnyObject? {
            if (key == "gameStatus") {
                return self.gameStatus
            } else if (key == "country") {
                return self.country
            } else if (key == "isSelected") {
                return self.isSelected
            } else {
                return nil
            }
        }
    }
    

    【讨论】:

    • 此代码不起作用。 warning: object 0x7fed10e19f50 of class '__lldb_expr_118.GameInfo' does not implement methodSignatureForSelector: -- trouble ahead Unrecognized selector -[__lldb_expr_118.GameInfo valueForKeyPath:]
    • 我错过了一些东西。为了使用 NSSortDescriptor,我们 GameInfo 类必须继承 NSObject 类然后覆盖 valueForKey。我更新了我对此解决方案的答案。否则,您可以在 .sort 函数中为 swift 实现自己的规则(请参阅 appzYourLife 的答案)
    • 如上实现GameInfo类,它必须工作。
    【解决方案3】:

    试试这个。

    你的班级如下所示

    import UIKit
    
    class GameInfo : NSObject {
    
        var gameStatus :String = ""
        var country : String = ""
        var isSelected : Bool = false
    
        init(gameStatus: String, country: String, isSelected: Bool) {
            self.gameStatus = gameStatus
            self.country = country
            self.isSelected = isSelected
        }
    }
    

    并使用此代码进行排序。您可以根据需要设置ascending参数。

    let list :NSArray = [
        GameInfo(gameStatus: "*", country: "Italy", isSelected: true),
        GameInfo(gameStatus: "1/2/21", country: "France", isSelected: true),
        GameInfo(gameStatus: "1-0", country: "UK", isSelected: true),
        GameInfo(gameStatus: "*", country: "Germany", isSelected: false),
        GameInfo(gameStatus: "0-1", country: "Italy", isSelected: true),
        GameInfo(gameStatus: "1/2-1/2", country: "UK", isSelected: false)
    ]
    
    let isSelectedDescriptor: NSSortDescriptor = NSSortDescriptor(key: "isSelected", ascending: false)
    let gameStatusDescriptor: NSSortDescriptor = NSSortDescriptor(key: "gameStatus", ascending: true)
    let countryDescriptor: NSSortDescriptor = NSSortDescriptor(key: "country", ascending: true)
    
    
    let sortedResults: NSArray = list.sortedArrayUsingDescriptors([isSelectedDescriptor,gameStatusDescriptor,countryDescriptor])
    
    dump(sortedResults)
    

    【讨论】:

    • @downvoter : 请同时给出理由,以便我以后记住,如果没有理由,请随意投反对票..
    猜你喜欢
    • 2015-11-19
    • 2021-06-15
    • 1970-01-01
    • 2016-06-20
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    • 2018-08-10
    相关资源
    最近更新 更多