繁体   English   中英

快速使用不同的参数对自定义对象数组进行排序

[英]Sorting Custom Object Array in swift with different parameter

我有一个自定义类的数组

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

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

我想gameStatus 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),

试试这个(旧式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
        }
    }
}

解决方案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()

尝试这个。

您的班级如下所示

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
    }
}

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

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)

暂无
暂无

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

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