Arrays 通过数组进行排序,不包括Nil
我试图对包含零变量的数组进行排序Arrays 通过数组进行排序,不包括Nil,arrays,swift,sorting,Arrays,Swift,Sorting,我试图对包含零变量的数组进行排序 class TestArray { var a: String? = nil var b: String? = nil init(a: String?, b: String?) { self.a = a self.b = b } } let first = TestArray(a: "xxx", b: "yyy") let second = TestArray(a: "zzz", b: "zzz"
class TestArray {
var a: String? = nil
var b: String? = nil
init(a: String?, b: String?) {
self.a = a
self.b = b
}
}
let first = TestArray(a: "xxx", b: "yyy")
let second = TestArray(a: "zzz", b: "zzz")
let third = TestArray(a: "aaa", b: nil)
var array = [first, second, third]
array.sort(by: {($0.a as String!) > ($1.a as String!)})
array.sort(by: {($0.b as String!) > ($1.b as String!)}) // Throws an error
如何按b
排序,并在数组末尾保留第三个TestArray的b=nil?
此外,我还想对所有b进行排序,然后对b=nil的数组按a对剩余的进行排序。我认为这应该涵盖您想要的情况,而不必重复多次(这很昂贵)
array.sort{(lessThan,item)->Bool-in
开关(lessThan.a,lessThan.b,项目a,项目b){
//如果存在bs,则使用该比较
格(u,.some(let lessThanB),u,.some(let itemB)):
返回lessThanB
我认为这应该涵盖您想要的情况,而不必重复多次(这很昂贵)
array.sort{(lessThan,item)->Bool-in
开关(lessThan.a,lessThan.b,项目a,项目b){
//如果存在bs,则使用该比较
格(u,.some(let lessThanB),u,.some(let itemB)):
返回lessThanB
如果您不需要进行适当的排序,您可以简单地应用您描述的“算法”以暴力方式对数组进行排序,使用多个过滤器对子集数组进行排序
“算法”:
- 主要按
b
属性排序,前提是它不是nil
- 对于
b
属性为nil
的元素,按a
属性排序
- 将
a
和b
均为nil
的元素保留在排序数组的末尾
例如:
//让我们设置一个更有趣的示例
let first=TestArray(a:“xxx”,b:“yyy”)
设秒=测试阵列(a:“ccc”,b:无)
让第三个=测试阵列(a:aaa,b:nil)
让第四个=测试阵列(a:“zzz”,b:“zzz”)
let fifth=TestArray(a:“bbb”,b:无)
var数组=[第一、第二、第三、第四、第五]
设sorted=array.filter{$0.b!=nil}.sorted{$0.b!<$1.b!}+
array.filter{$0.b==nil&&$0.a!=nil}.sorted{$0.a!<$1.a!}+
array.filter{$0.b==nil&&$0.a==nil}
sorted.enumerated().forEach{print(\($0):b:\($1.b),a:\($1.a)}
/*0:b:可选(“yyy”)、a:可选(“xxx”)
1:b:可选(“zzz”),a:可选(“zzz”)
2:b:无,a:可选(“aaa”)
3:b:无,a:可选(“bbb”)
4:b:无,a:可选(“ccc”)*/
如果您不需要进行适当的排序,您可以简单地应用您描述的“算法”以暴力方式对数组进行排序,使用多个过滤器对子集数组进行排序
“算法”:
- 主要按
b
属性排序,前提是它不是nil
- 对于
b
属性为nil
的元素,按a
属性排序
- 将
a
和b
均为nil
的元素保留在排序数组的末尾
例如:
//让我们设置一个更有趣的示例
let first=TestArray(a:“xxx”,b:“yyy”)
设秒=测试阵列(a:“ccc”,b:无)
让第三个=测试阵列(a:aaa,b:nil)
让第四个=测试阵列(a:“zzz”,b:“zzz”)
let fifth=TestArray(a:“bbb”,b:无)
var数组=[第一、第二、第三、第四、第五]
设sorted=array.filter{$0.b!=nil}.sorted{$0.b!<$1.b!}+
array.filter{$0.b==nil&&$0.a!=nil}.sorted{$0.a!<$1.a!}+
array.filter{$0.b==nil&&$0.a==nil}
sorted.enumerated().forEach{print(\($0):b:\($1.b),a:\($1.a)}
/*0:b:可选(“yyy”)、a:可选(“xxx”)
1:b:可选(“zzz”),a:可选(“zzz”)
2:b:无,a:可选(“aaa”)
3:b:无,a:可选(“bbb”)
4:b:无,a:可选(“ccc”)*/
在我看来,以下是最好的方法:
首先,我定义了一个,我认为这是最好的方法:
首先,我定义了一个您希望nil如何与非nil值进行比较?如果一些TestArray具有“b=nil”,我希望使用这些值并按“a”排序。您遵循什么规则对元素进行精确排序?array.sort(by:{($0.a作为字符串!)>($1.a作为字符串!))您希望nil如何与非nil值进行比较?如果一些TestArray具有“b=nil”,我希望采用这些值并按“a”进行排序。您遵循什么规则对元素进行精确排序?array.sort(按:{($0.a作为字符串!)>($1.a作为字符串!))仅供参考,只需将第二种情况修复为(我想)更好地匹配您的需求。这是不必要的复杂,并且不能扩展到许多属性。另外,.none
可以短到nil
,和。一些(让x)
可以短到x?
。仅供参考,刚刚修复了第二种情况,以便(我认为)更好地匹配您的需求。这是不必要的复杂,并且不能扩展到许多属性。另外,.none
可以短于nil
,和。一些(设x)
可以短于x?
。仅供参考,您在数组上迭代了~6次。在小范围内,这无关紧要,但随着阵列的扩展,性能将降低6倍。@PEEJWEEJ因此在
array.sort { (lessThan, item) -> Bool in
switch (lessThan.a, lessThan.b, item.a, item.b) {
// if bs exist, use that comparison
case (_, .some(let lessThanB), _, .some(let itemB)):
return lessThanB < itemB
// if bs don't exist by as do, use that comparison
case (.some(let lessThanA), .none, .some(let itemA), .none):
return lessThanA < itemA
// if one item has a value but the other doesn't, the item with the value should be first
case (_, .some(_), _, .none), (.some(_), _, .none, _ ):
return true
default:
return false
}
}
// lets set up a more interesting example
let first = TestArray(a: "xxx", b: "yyy")
let second = TestArray(a: "ccc", b: nil)
let third = TestArray(a: "aaa", b: nil)
let fourth = TestArray(a: "zzz", b: "zzz")
let fifth = TestArray(a: "bbb", b: nil)
var array = [first, second, third, fourth, fifth]
let sorted = array.filter { $0.b != nil }.sorted { $0.b! < $1.b! } +
array.filter { $0.b == nil && $0.a != nil }.sorted { $0.a! < $1.a! } +
array.filter { $0.b == nil && $0.a == nil }
sorted.enumerated().forEach { print("\($0): b: \($1.b), a: \($1.a)") }
/* 0: b: Optional("yyy"), a: Optional("xxx")
1: b: Optional("zzz"), a: Optional("zzz")
2: b: nil, a: Optional("aaa")
3: b: nil, a: Optional("bbb")
4: b: nil, a: Optional("ccc") */
fileprivate func <(a: String?, b: String?) -> Bool {
switch (a, b) {
case (nil, nil): return false
case (nil, _?): return true
case (_?, nil): return false
case (let a?, let b?): return a < b
}
}
struct TestStruct {
var a: String?
var b: String?
}
let input = [
TestStruct(a: "xxx", b: "yyy"),
TestStruct(a: "zzz", b: "zzz"),
TestStruct(a: "aaa", b: nil)
]
let output = input.sorted { lhs, rhs in
if lhs.a != rhs.a { return lhs.a < rhs.a } // first sort by a
if lhs.b != rhs.b { return lhs.b < rhs.b } // then sort by b
return true
}
print(output)
//[
// TempCode.TestStruct(a: Optional("aaa"), b: nil),
// TempCode.TestStruct(a: Optional("xxx"), b: Optional("yyy")),
// TempCode.TestStruct(a: Optional("zzz"), b: Optional("zzz"))
//]
extension TestStruct: Equatable {
public static func ==(lhs: TestStruct, rhs: TestStruct) -> Bool {
return
lhs.a == rhs.a &&
lhs.b == rhs.b
}
}
extension TestStruct: Comparable {
public static func <(lhs: TestStruct, rhs: TestStruct) -> Bool {
if lhs.a != rhs.a { return lhs.a < rhs.a } // first sort by a
if lhs.b != rhs.b { return lhs.b < rhs.b } // then sort by b
return true
}
}
let output = input.sorted()