Ios swift-根据对象的可选布尔属性对对象数组进行排序,无需强制展开

Ios swift-根据对象的可选布尔属性对对象数组进行排序,无需强制展开,ios,swift,Ios,Swift,我可以按“旗舰”布尔属性对存储对象数组进行排序,但如何首先安全地打开“旗舰”属性 let flagshipStores = self.stores.sort { $0.flagship! && !$1.flagship! } 那么: let flagshipStores = self.stores.sort { $0.flagship! && !$1.flagship! } $0.flagship == true && $1.f

我可以按“旗舰”布尔属性对存储对象数组进行排序,但如何首先安全地打开“旗舰”属性

let flagshipStores = self.stores.sort {
    $0.flagship! && !$1.flagship!
}
那么:

let flagshipStores = self.stores.sort {
    $0.flagship! && !$1.flagship!
}
$0.flagship == true && $1.flagship != true

如果值不是nil且为true,左侧将成功,如果值为nil或false,右侧将成功。

这里是另一种方法

let flagshipStores = self.stores.sort {
    $0.flagship! && !$1.flagship!
}
let flagshipStores = self.stores.sort {
    guard let flagship0 = $0.flagship, let flagship1 = $1.flagship else { return false }
    return flagship0 && !flagship1
}
您可以使用
flatMap
,它将删除
nil
对象并展开存在的对象。然后,强制展开可以安全地进行排序:

let flagshipStores = self.stores.sort {
    $0.flagship! && !$1.flagship!
}
let flagshipStores = stores.flatMap({ return $0.flagship ? $0 : nil }).sort {
    $0.flagship! && !$1.flagship!
}

这将从阵列中删除具有
nil
旗舰的存储。

还有一种方法:将
Bool?
转换为
Int
,然后比较
Int
s。您可以指定
nil
值与非
nil
值的比较方式

let flagshipStores = self.stores.sort {
    $0.flagship! && !$1.flagship!
}
例如,这会将
nil
值排序在
false
true
之前:

let flagshipStores = self.stores.sort {
    $0.flagship! && !$1.flagship!
}
stores.sort { Int($0.flagship ?? -1) < Int($1.flagship ?? -1) }
stores.sort { Int($0.flagship ?? 2) < Int($1.flagship ?? 2) }

您可以使用相同的模式将
nil
true
false
进行比较。这取决于你。

正如菲希特先生在评论中指出的那样,被接受的答案并不完全有效,因为它不考虑零。下面是一个额外的字符串示例的正确答案

let flagshipStores = self.stores.sort {
    $0.flagship! && !$1.flagship!
}
斯威夫特4

let flagshipStores = self.stores.sort {
    $0.flagship! && !$1.flagship!
}
对于布尔排序

let flagshipStores = self.stores.sort {
    $0.flagship! && !$1.flagship!
}
 let flagshipStores = self.stores.sorted(by: {
    guard let flagship0 = $0.flagship, let flagship1 = $1.flagship else { 

       if $0.flagship == nil && $1.flagship == nil || $0.flagship != nil &&  $1.flagship == nil{

          return true

       }
       else {

          return false

       }
    } 

    return ($0.flagship == $1.flagship || $0.flagship == true && $1.flagship == false ? true : false)


 })
用于字符串比较排序

let flagshipStores = self.stores.sort {
    $0.flagship! && !$1.flagship!
}
 let stores = self.stores.sorted(by: {
    guard let store0 = $0.store, let store1 = $1.store else { 

       if $0.store == nil && $1.store == nil || $0.store != nil &&  $1.store == nil{

          return true

       }
       else {

          return false

       }
    } 

    return ( ($0.store)?.localizedStandardCompare($1.store!) == ComparisonResult.orderedAscending )

 })

要过滤
nil
值,只需在
排序之前使用
compactMap

let flagshipStores = self.stores.sort {
    $0.flagship! && !$1.flagship!
}
let flagshipStores = self.stores.compactMap { return $0.flagship }.sorted {
    $0 && !$1
}

我会考虑在您的设计中是否真的需要二进制类型的“第三状态”(可选Bool)?不幸的是,这不是我的设计。我正在解析一个JSON对象,其中flagship可能为true、false或未提供。您能将未提供视为false吗?我同意@vadian,但您可以使用nil coalescing操作符提供默认值
false
,但这确实是您解包JSON时应该做的事情。这里有一个bug。如果只有一个是nil,则此代码返回“false”,但它应该返回($0.flagship==nil&&$1.flagship!=nil)(如果希望nil在非nil之前排序)。