如何在不更改主数组中原始顺序的情况下按 BOOL 对 swift 进行排序?
How to sort in swift by a BOOL without changing the original order in main array?
我有一组具有 2 个属性的模型:
1.标题(字符串)
2。 isSelected (布尔)
我想根据 isSelected
属性 对它们进行排序,使其相对于源数组的顺序进行排序。例如,如果全部为 FALSE 或 TRUE,则在排序后应该有相同的输出。
但是,如果我使用以下方法,它会在根据该 BOOL 属性.
对它们进行排序后改变原始排序
someArray = array.sort { [=11=].selected && !.selected }
我应该怎么做才能保留原始序列?
EDIT 1
title
的排序顺序不在图片中。可能是服务器向我发送了 4 objects,标题为 Z、Y、P、A。所以如果所有都是假的,一旦我排序,它应该像 Z false,Y false, P false, A false.
你需要
someArray = array.sorted (by:{ [=10=].selected && !.selected && <#Add more conditions #>})
sorted (by
不像 sort
那样改变原始数组
https://developer.apple.com/documentation/swift/array/1688499-sort
https://developer.apple.com/documentation/swift/array/2296815-sorted
您应该使用 sorted
方法而不是 sort
;
let newArray = array.sorted { [=10=].selected && !.selected }
基本上sort
在同一个数组中排序,sorted
return一个新的数组,不改变原来的
如果你想保留从服务器获得的顺序,我建议你不要使用 sort
或 sorted
方法,因为它们不能保证保留密钥的原始顺序同样的顺序。我会建议您编写自己的类似排序的函数:
struct Model {
let title:String
let selected:Bool
}
let array = [ Model(title: "Z", selected: true), Model(title: "Z", selected: false), Model(title: "Y", selected: false), Model(title: "P", selected: false), Model(title: "A", selected: true), Model(title: "A", selected: false)]
extension Array where Element == Model {
func preserveSorted() -> [Model] {
var selected:[Model] = []
var notSelected:[Model] = []
for model in self {
if model.selected {
selected.append(model)
} else {
notSelected.append(model)
}
}
var output:[Model] = []
output.append(contentsOf: selected)
output.append(contentsOf: notSelected)
return output
}
}
var newArray:[Model] = array.preserveSorted()
print(newArray)
/* output:
[
Model(title: "Z", selected: true),
Model(title: "A", selected: true),
Model(title: "Z", selected: false),
Model(title: "Y", selected: false),
Model(title: "P", selected: false),
Model(title: "A", selected: false)
]
*/
如果您不想为您的模型创建 Comparable
扩展(例如,因为您在一些地方使用了不同顺序的这些模型),您可以使用方法 sorted
,但提供不同的排序块:
struct Model {
let title:String
let selected:Bool
}
let array = [ Model(title: "a", selected: true), Model(title: "a", selected: false), Model(title: "b", selected: false), Model(title: "c", selected: true)]
let newArray = array.sorted { (lhs, rhs) -> Bool in
if lhs.selected == rhs.selected {
return lhs.title < rhs.title
}
return lhs.selected
}
print(newArray)
排序顺序为:
[
Model(title: "a", selected: true),
Model(title: "c", selected: true),
Model(title: "a", selected: false),
Model(title: "b", selected: false)
]
您可以使用过滤操作更有效地代替排序:
let newArray = array.filter { [=10=].selected } + array.filter { ![=10=].selected }
不幸的是,Array.sorted
不能保证排序稳定,因此您不能仅按一个 属性 排序并期望保留原始排序。
不过您可以轻松实现稳定排序(例如 )
那么你可以简单地使用:
let newArray = array.stableSorted {
let numeric1 = [=11=].selected ? 0 : 1
let numeric2 = .selected ? 0 : 1
return numeric1 <= numeric2
}
或
let newArray = array.stableSorted {
return [=12=].selected == .selected || [=12=].selected
}
我有一组具有 2 个属性的模型:
1.标题(字符串)
2。 isSelected (布尔)
我想根据 isSelected
属性 对它们进行排序,使其相对于源数组的顺序进行排序。例如,如果全部为 FALSE 或 TRUE,则在排序后应该有相同的输出。
但是,如果我使用以下方法,它会在根据该 BOOL 属性.
对它们进行排序后改变原始排序someArray = array.sort { [=11=].selected && !.selected }
我应该怎么做才能保留原始序列?
EDIT 1
title
的排序顺序不在图片中。可能是服务器向我发送了 4 objects,标题为 Z、Y、P、A。所以如果所有都是假的,一旦我排序,它应该像 Z false,Y false, P false, A false.
你需要
someArray = array.sorted (by:{ [=10=].selected && !.selected && <#Add more conditions #>})
sorted (by
不像 sort
https://developer.apple.com/documentation/swift/array/1688499-sort
https://developer.apple.com/documentation/swift/array/2296815-sorted
您应该使用 sorted
方法而不是 sort
;
let newArray = array.sorted { [=10=].selected && !.selected }
基本上sort
在同一个数组中排序,sorted
return一个新的数组,不改变原来的
如果你想保留从服务器获得的顺序,我建议你不要使用 sort
或 sorted
方法,因为它们不能保证保留密钥的原始顺序同样的顺序。我会建议您编写自己的类似排序的函数:
struct Model {
let title:String
let selected:Bool
}
let array = [ Model(title: "Z", selected: true), Model(title: "Z", selected: false), Model(title: "Y", selected: false), Model(title: "P", selected: false), Model(title: "A", selected: true), Model(title: "A", selected: false)]
extension Array where Element == Model {
func preserveSorted() -> [Model] {
var selected:[Model] = []
var notSelected:[Model] = []
for model in self {
if model.selected {
selected.append(model)
} else {
notSelected.append(model)
}
}
var output:[Model] = []
output.append(contentsOf: selected)
output.append(contentsOf: notSelected)
return output
}
}
var newArray:[Model] = array.preserveSorted()
print(newArray)
/* output:
[
Model(title: "Z", selected: true),
Model(title: "A", selected: true),
Model(title: "Z", selected: false),
Model(title: "Y", selected: false),
Model(title: "P", selected: false),
Model(title: "A", selected: false)
]
*/
如果您不想为您的模型创建 Comparable
扩展(例如,因为您在一些地方使用了不同顺序的这些模型),您可以使用方法 sorted
,但提供不同的排序块:
struct Model {
let title:String
let selected:Bool
}
let array = [ Model(title: "a", selected: true), Model(title: "a", selected: false), Model(title: "b", selected: false), Model(title: "c", selected: true)]
let newArray = array.sorted { (lhs, rhs) -> Bool in
if lhs.selected == rhs.selected {
return lhs.title < rhs.title
}
return lhs.selected
}
print(newArray)
排序顺序为:
[
Model(title: "a", selected: true),
Model(title: "c", selected: true),
Model(title: "a", selected: false),
Model(title: "b", selected: false)
]
您可以使用过滤操作更有效地代替排序:
let newArray = array.filter { [=10=].selected } + array.filter { ![=10=].selected }
不幸的是,Array.sorted
不能保证排序稳定,因此您不能仅按一个 属性 排序并期望保留原始排序。
不过您可以轻松实现稳定排序(例如
那么你可以简单地使用:
let newArray = array.stableSorted {
let numeric1 = [=11=].selected ? 0 : 1
let numeric2 = .selected ? 0 : 1
return numeric1 <= numeric2
}
或
let newArray = array.stableSorted {
return [=12=].selected == .selected || [=12=].selected
}