如何使用已排序的元组对数组进行排序?(不能用类型的参数列表来调用“排序”)

时间:2021-06-03 16:01:17

I am trying to sort an array of tuples using sorted.

我正在尝试使用已排序的元组对数组进行排序。

The error I get is:

我得到的错误是:

Cannot invoke 'sorted' with an argument list of type (((MyClass1, MyClass2)) -> Bool)

不能使用类型为((MyClass1, MyClass2) -> Bool)的参数列表调用“已排序”

The array is created like this:

数组是这样创建的:

class MyClass1 {
    var id: Int
    init(id:Int) { self.id = id }
}

class MyClass2 {
    var id2: Int
    init(id2:Int) { self.id2 = id2 }
}
let array1 = [MyClass1(id:4), MyClass1(id:3), MyClass1(id:2), MyClass1(id:1)]
let array2 = [MyClass2(id2:1), MyClass2(id2:2), MyClass2(id2:3), MyClass2(id2:4)]
var tuples = zip(array1, array2)

What I have tried:

我已经尝试:

tuples = tuples.sorted { (left, right) -> Bool in
    return left.1.id2 > right.1.id2
}

tuples = tuples.sorted { $0.1.id2 > $1.1.id2 }

tuples = tuples.sorted(by: { (first: (MyClass1, MyClass2), second: (MyClass1, MyClass2)) -> Bool in
    return first.1.id2 > second.1.id2
})

The expected output is(pseudo, handwritten):

期望输出为(伪,手写):

[(myClass1WithId_1, myClass2WithId2_4),(myClass1WithId_2, myClass2WithId2_3),(myClass1WithId_3, myClass2WithId2_2),(myClass1WithId_4, myClass2WithId2_1)]

The tuples sorted by myClass2.id2 descending.

按myClass2排序的元组。id2下行。


Update

更新

I found out how to workaround the issue. The error seems to be wrong/misleading.

我找到了解决这个问题的办法。这个错误似乎是错误的。

I can sort it when assigning the result to a new variable:

我可以将结果分配给一个新变量时进行排序:

let tuples2 = tuples.sorted { (left, right) -> Bool in
    return left.1.id2 > right.1.id2
}

while assigning it to the existing variable gives me the mentioned error:

当把它赋给现有变量时,我得到了上面提到的错误:

tuples = tuples.sorted { (left, right) -> Bool in
    return left.1.id2 > right.1.id2
}

2 个解决方案

#1


1  

I am trying to sort an array of tuples

我正在尝试对一组元组进行排序

But problem is that your tuples is not an array. (It is a thing called a Zip2Sequence.) The solution is to coerce it to an array:

但是问题是你的元组不是数组。(它被称为Zip2Sequence。)解决方案是将它强制到一个数组中:

var tuples = Array(zip(array1, array2))

Now your original code will work:

现在你的原始代码可以工作了:

let array1 = [MyClass1(id:4), MyClass1(id:3), MyClass1(id:2), MyClass1(id:1)]
let array2 = [MyClass2(id2:1), MyClass2(id2:2), MyClass2(id2:3), MyClass2(id2:4)]
var tuples = Array(zip(array1, array2)) // *
tuples = tuples.sorted { (left, right) -> Bool in
    return left.1.id2 > right.1.id2
}

The reason your solution worked is that a sorted sequence yields an array. So you can't reassign the array to the sequence variable (tuples) but you can assign it to a different variable (tuples2). My solution starts with an array, so the resulting sorted array can be assigned back to the same variable.

您的解决方案起作用的原因是排序序列产生一个数组。因此不能将数组重新分配给序列变量(元组),但可以将其分配给另一个变量(tuples2)。我的解决方案从一个数组开始,所以得到的排序数组可以被分配回相同的变量。

#2


0  

You're not able to use sorted() because the tuple type (MyClass1, MyClass2) does not conform to Comparable, so the sorter would not know how to sort your tuples. You can't add an extension that adds conformance to it either, because tuples can't have extensions or conform to protocols.

您不能使用排序(),因为tuple类型(MyClass1, MyClass2)不符合可比性,所以sorter不知道如何排序您的元组。您也不能添加一个添加一致性的扩展,因为元组不能有扩展或符合协议。

You can however, use sorted(by:), which requires you give a closure which defines the sorting between elements.

但是,您可以使用排序(by:),这需要您给出一个闭包,该闭包定义了元素之间的排序。

class MyClass1 {
    var id: Int
    init(id:Int) { self.id = id }
}

class MyClass2 {
    var id2: Int
    init(id2:Int) { self.id2 = id2 }
}
let array1 = [MyClass1(id:4), MyClass1(id:3), MyClass1(id:2), MyClass1(id:1)]
let array2 = [MyClass2(id2:1), MyClass2(id2:2), MyClass2(id2:3), MyClass2(id2:4)]
let tuples = zip(array1, array2)

let sortedTuples = tuples.sorted{ $0.1.id2 > $1.1.id2 }

print(sortedTuples)

#1


1  

I am trying to sort an array of tuples

我正在尝试对一组元组进行排序

But problem is that your tuples is not an array. (It is a thing called a Zip2Sequence.) The solution is to coerce it to an array:

但是问题是你的元组不是数组。(它被称为Zip2Sequence。)解决方案是将它强制到一个数组中:

var tuples = Array(zip(array1, array2))

Now your original code will work:

现在你的原始代码可以工作了:

let array1 = [MyClass1(id:4), MyClass1(id:3), MyClass1(id:2), MyClass1(id:1)]
let array2 = [MyClass2(id2:1), MyClass2(id2:2), MyClass2(id2:3), MyClass2(id2:4)]
var tuples = Array(zip(array1, array2)) // *
tuples = tuples.sorted { (left, right) -> Bool in
    return left.1.id2 > right.1.id2
}

The reason your solution worked is that a sorted sequence yields an array. So you can't reassign the array to the sequence variable (tuples) but you can assign it to a different variable (tuples2). My solution starts with an array, so the resulting sorted array can be assigned back to the same variable.

您的解决方案起作用的原因是排序序列产生一个数组。因此不能将数组重新分配给序列变量(元组),但可以将其分配给另一个变量(tuples2)。我的解决方案从一个数组开始,所以得到的排序数组可以被分配回相同的变量。

#2


0  

You're not able to use sorted() because the tuple type (MyClass1, MyClass2) does not conform to Comparable, so the sorter would not know how to sort your tuples. You can't add an extension that adds conformance to it either, because tuples can't have extensions or conform to protocols.

您不能使用排序(),因为tuple类型(MyClass1, MyClass2)不符合可比性,所以sorter不知道如何排序您的元组。您也不能添加一个添加一致性的扩展,因为元组不能有扩展或符合协议。

You can however, use sorted(by:), which requires you give a closure which defines the sorting between elements.

但是,您可以使用排序(by:),这需要您给出一个闭包,该闭包定义了元素之间的排序。

class MyClass1 {
    var id: Int
    init(id:Int) { self.id = id }
}

class MyClass2 {
    var id2: Int
    init(id2:Int) { self.id2 = id2 }
}
let array1 = [MyClass1(id:4), MyClass1(id:3), MyClass1(id:2), MyClass1(id:1)]
let array2 = [MyClass2(id2:1), MyClass2(id2:2), MyClass2(id2:3), MyClass2(id2:4)]
let tuples = zip(array1, array2)

let sortedTuples = tuples.sorted{ $0.1.id2 > $1.1.id2 }

print(sortedTuples)