Ios 按指定索引对数组排序,在保持字母顺序的同时对布尔值进行优先级排序

Ios 按指定索引对数组排序,在保持字母顺序的同时对布尔值进行优先级排序,ios,arrays,swift,sorting,Ios,Arrays,Swift,Sorting,这个有点傻 基于,我根据另一个数组中的索引对对象数组重新排序: // pop this in a playground: struct DataObject { let id: String let name: String let isRequired: Bool init(_ id: String, _ name: String, _ isRequired: Bool) { self.id = id self.name =

这个有点傻

基于,我根据另一个数组中的索引对对象数组重新排序:

// pop this in a playground:

struct DataObject {
    let id: String
    let name: String
    let isRequired: Bool

    init(_ id: String, _ name: String, _ isRequired: Bool) {
        self.id = id
        self.name = name
        self.isRequired = isRequired
    }
}

struct User {
    let sortingIndex: [String]

    init(_ sortingIndex: [String]) {
        self.sortingIndex = sortingIndex
    }
}


let a = [DataObject("1", "A", false), DataObject("2", "B", true), DataObject("3", "C", true), DataObject("4", "D", false)]

func sort(a: [DataObject], forUser user: User) -> [DataObject] {
    return a.sort { user.sortingIndex.indexOf($0.id) < user.sortingIndex.indexOf($1.id) }
}

let user = User(["1", "2", "4", "3"])

sort(a, forUser: user)
(大部分都很好!)

我想按字母顺序排列数组开头的
I所需的
的优先级,因此我尝试:

return a.sort { $0.isRequired ? $0.name < $1.name : user.sortingIndex.indexOf($0.id) < user.sortingIndex.indexOf($1.id) }
                                     \\ ^

您可以为
Bool
值定义
运算符,并使用该运算符对对象数组进行排序:

func >(lhs: Bool, rhs: Bool) -> Bool {
    return lhs && !rhs
}

let sortedObjects = sort(a, forUser: user).sort{$0.isRequired > $1.isRequired || $0.name < $1.name}
func>(左:布尔,右:布尔)->Bool{
返回左侧和右侧
}
让sortedObjects=sort(a,forUser:user)。sort{$0.isRequired>1.isRequired | |$0.name<$1.name}

当只需要
$0
$1
中的一个时,无论名称如何,都应分别返回
true
false
。因此,类似这样的方法会起作用:

return a.sort {
        if $0.isRequired && $1.isRequired {
            return $0.name < $1.name
        }
        if $0.isRequired { return true }
        if $1.isRequired { return false }
        return user.sortingIndex.indexOf($0.id) < user.sortingIndex.indexOf($1.id)
    }
返回a.sort{
如果需要0.1美元&&1.1美元{
返回$0.name<$1.name
}
如果需要$0.1{返回真值}
如果需要$1.0{返回false}
返回user.sortingIndex.indexOf($0.id)
将排序更改为:

a.sort { (lhs, rhs) -> Bool in
    if lhs.isRequired != rhs.isRequired { return lhs.isRequired }
    if lhs.name != hrs.name {return lhs.name < rhs.name}
    return user.sortingIndex.indexOf(lhs.id) < user.sortingIndex.indexOf(rhs.id)
}
a.sort{(lhs,rhs)->Bool-in
如果lhs.isRequired!=rhs.isRequired{返回lhs.isRequired}
如果lhs.name!=hrs.name{返回lhs.name

首先检查isRequired,然后检查名称,最后检查用户索引。

这里有一个可爱的方法:

return a.sort({  $0.isRequired != $1.isRequired   ? $0.isRequired
               : $0.isRequired                    ? $0.name < $1.name
               : user.sortingIndex.indexOf($0.id) < user.sortingIndex.indexOf($1.id)
              })
返回a.sort({$0.isRequired!=$1.isRequired?$0.isRequired
:$0.i是否需要?$0.name<$1.name
:user.sortingIndex.indexOf($0.id)
您的排序是一种不同级别的排序,但在更一般的情况下,多级排序条件始终具有相同的模式:

  $0.level1 != $1.level1     ? $0.level1 < $1.level1
: $0.level2 != $1.level2     ? $0.level2 < $1.level2
...
: $0.levelN-1 != $1.levelN-1 ? $0.levelN-1 < $1.levelN-1
: $0.levelN < $1.levelN
$0.level1!=$1.1级$0.1级<$1.1级
:$0.2级!=$1.2级$0.2级<1.2级
...
:$0.1级n-1!=$1.n-1级$0.levelN-1<$1.levelN-1
:$0.levelN<$1.levelN

我详细查看了每个答案,但我发现这一个实际上是最简洁的,而且是一行一行的废话!除了编译器抛出这个⊙_⚆ 表达式过于复杂,无法在合理的时间内解决;考虑把表达式分解成不同的子表达式。我想我还是得换一个——虽然这在游乐场环境中有效,但在项目中却不起作用。奇怪的是,我以前用过更复杂的。也许你可以使用字典让你的user.sortIndex类工作,使它更紧凑/简洁(也更快启动)。我刚刚又试了一次,它工作了(在操场上)。
a.sort { (lhs, rhs) -> Bool in
    if lhs.isRequired != rhs.isRequired { return lhs.isRequired }
    if lhs.name != hrs.name {return lhs.name < rhs.name}
    return user.sortingIndex.indexOf(lhs.id) < user.sortingIndex.indexOf(rhs.id)
}
return a.sort({  $0.isRequired != $1.isRequired   ? $0.isRequired
               : $0.isRequired                    ? $0.name < $1.name
               : user.sortingIndex.indexOf($0.id) < user.sortingIndex.indexOf($1.id)
              })
  $0.level1 != $1.level1     ? $0.level1 < $1.level1
: $0.level2 != $1.level2     ? $0.level2 < $1.level2
...
: $0.levelN-1 != $1.levelN-1 ? $0.levelN-1 < $1.levelN-1
: $0.levelN < $1.levelN