我有一组具有2个属性的模型:
1。标题(字符串)
2。已选择(布尔)
我想基于selected
属性对它们进行排序,以使其相对于源数组的顺序起作用。例如,如果全部为FALSE或TRUE,则订购后应该有相同的输出。
但是,如果我使用following,它会根据该BOOL属性对原始排序进行排序后更改原始排序。
someArray = array.sort { $0.selected && !$1.selected }
我该怎么做才能保留原始顺序?
编辑1:
Title
的排序顺序没有出现。可能是服务器向我发送了标题为Z,Y,P,A的4个对象。因此,如果全部为假,并且一旦我进行排序,就应该像Z假,Y假,P假,A假。
答案 0 :(得分:3)
您需要
someArray = array.sorted (by:{ $0.selected && !$1.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
答案 1 :(得分:1)
您应该使用sorted
方法而不是sort
;
let newArray = array.sorted { $0.selected && !$1.selected }
基本上sort
在同一数组中排序,sorted
返回一个新数组,而不更改原始数组
答案 2 :(得分:1)
如果要保留从服务器获得的顺序,我建议您不要使用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)
]
答案 3 :(得分:1)
代替排序,您可以使用过滤器操作更有效地做到这一点:
let newArray = array.filter { $0.selected } + array.filter { !$0.selected }
不幸的是,Array.sorted
不能保证稳定的排序,因此您不能仅按一个属性排序并希望保留原始排序。
尽管如此,您仍可以轻松实现稳定的排序(例如https://stackoverflow.com/a/50545761/669586)
然后您可以简单地使用:
let newArray = array.stableSorted {
let numeric1 = $0.selected ? 0 : 1
let numeric2 = $1.selected ? 0 : 1
return numeric1 <= numeric2
}
或
let newArray = array.stableSorted {
return $0.selected == $1.selected || $0.selected
}