moh*_*acs 474 arrays sorting swift
假设我们有一个名为imageFile的自定义类,该类包含两个属性.
class imageFile {
var fileName = String()
var fileID = Int()
}
Run Code Online (Sandbox Code Playgroud)
很多都存储在Array中
var images : Array = []
var aImage = imageFile()
aImage.fileName = "image1.png"
aImage.fileID = 101
images.append(aImage)
aImage = imageFile()
aImage.fileName = "image1.png"
aImage.fileID = 202
images.append(aImage)
Run Code Online (Sandbox Code Playgroud)
问题是:如何通过'fileID'ASC或DESC对图像数组进行排序?
Ale*_*yne 864
首先,将Array声明为类型化数组,以便在迭代时调用方法:
var images : [imageFile] = []
Run Code Online (Sandbox Code Playgroud)
然后你可以简单地做:
斯威夫特2
images.sorted({ $0.fileID > $1.fileID })
Run Code Online (Sandbox Code Playgroud)
斯威夫特3和4
images.sorted(by: { $0.fileID > $1.fileID })
Run Code Online (Sandbox Code Playgroud)
上面的例子给出了desc排序顺序
GoZ*_*ner 208
[ 更新了Swift 3 with sort(by :) ]这个,利用了一个尾随的闭包:
images.sorted { $0.fileID < $1.fileID }
Run Code Online (Sandbox Code Playgroud)
你在哪里使用<
或>
依赖于ASC或DESC. 如果要修改images
阵列,请使用以下命令:
images.sort { $0.fileID < $1.fileID }
Run Code Online (Sandbox Code Playgroud)
如果您要反复执行此操作并且更喜欢定义函数,则一种方法是:
func sorterForFileIDASC(this:imageFile, that:imageFile) -> Bool {
return this.fileID > that.fileID
}
Run Code Online (Sandbox Code Playgroud)
然后用作:
images.sort(by: sorterForFileIDASC)
Run Code Online (Sandbox Code Playgroud)
fuj*_*471 51
几乎每个人都给出了如何直接,让我展示演变:
你可以使用Array的实例方法:
// general form of closure
images.sortInPlace({ (image1: imageFile, image2: imageFile) -> Bool in return image1.fileID > image2.fileID })
// types of closure's parameters and return value can be inferred by Swift, so they are omitted along with the return arrow (->)
images.sortInPlace({ image1, image2 in return image1.fileID > image2.fileID })
// Single-expression closures can implicitly return the result of their single expression by omitting the "return" keyword
images.sortInPlace({ image1, image2 in image1.fileID > image2.fileID })
// closure's argument list along with "in" keyword can be omitted, $0, $1, $2, and so on are used to refer the closure's first, second, third arguments and so on
images.sortInPlace({ $0.fileID > $1.fileID })
// the simplification of the closure is the same
images = images.sort({ (image1: imageFile, image2: imageFile) -> Bool in return image1.fileID > image2.fileID })
images = images.sort({ image1, image2 in return image1.fileID > image2.fileID })
images = images.sort({ image1, image2 in image1.fileID > image2.fileID })
images = images.sort({ $0.fileID > $1.fileID })
Run Code Online (Sandbox Code Playgroud)
有关sort的工作原理的详细说明,请参阅排序函数.
que*_*ful 44
斯威夫特3
people = people.sorted(by: { $0.email > $1.email })
Run Code Online (Sandbox Code Playgroud)
Ima*_*tit 38
使用Swift 4,Array
有两种方法叫做sorted()
和sorted(by:)
.第一种方法sorted()
有以下声明:
返回集合的元素,已排序.
func sorted() -> [Element]
Run Code Online (Sandbox Code Playgroud)
第二种方法sorted(by:)
有以下声明:
返回集合的元素,使用给定的谓词作为元素之间的比较进行排序.
func sorted(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> [Element]
Run Code Online (Sandbox Code Playgroud)
如果集合中的元素类型符合Comparable
协议,则可以使用sorted()
以按升序对元素进行排序.以下Playground代码显示了如何使用sorted()
:
class ImageFile: CustomStringConvertible, Comparable {
let fileName: String
let fileID: Int
var description: String { return "ImageFile with ID: \(fileID)" }
init(fileName: String, fileID: Int) {
self.fileName = fileName
self.fileID = fileID
}
static func ==(lhs: ImageFile, rhs: ImageFile) -> Bool {
return lhs.fileID == rhs.fileID
}
static func <(lhs: ImageFile, rhs: ImageFile) -> Bool {
return lhs.fileID < rhs.fileID
}
}
let images = [
ImageFile(fileName: "Car", fileID: 300),
ImageFile(fileName: "Boat", fileID: 100),
ImageFile(fileName: "Plane", fileID: 200)
]
let sortedImages = images.sorted()
print(sortedImages)
/*
prints: [ImageFile with ID: 100, ImageFile with ID: 200, ImageFile with ID: 300]
*/
Run Code Online (Sandbox Code Playgroud)
如果集合中的元素类型符合Comparable
协议,则必须使用sorted(by:)
以按降序对元素进行排序.
class ImageFile: CustomStringConvertible, Comparable {
let fileName: String
let fileID: Int
var description: String { return "ImageFile with ID: \(fileID)" }
init(fileName: String, fileID: Int) {
self.fileName = fileName
self.fileID = fileID
}
static func ==(lhs: ImageFile, rhs: ImageFile) -> Bool {
return lhs.fileID == rhs.fileID
}
static func <(lhs: ImageFile, rhs: ImageFile) -> Bool {
return lhs.fileID < rhs.fileID
}
}
let images = [
ImageFile(fileName: "Car", fileID: 300),
ImageFile(fileName: "Boat", fileID: 100),
ImageFile(fileName: "Plane", fileID: 200)
]
let sortedImages = images.sorted(by: { (img0: ImageFile, img1: ImageFile) -> Bool in
return img0 > img1
})
//let sortedImages = images.sorted(by: >) // also works
//let sortedImages = images.sorted { $0 > $1 } // also works
print(sortedImages)
/*
prints: [ImageFile with ID: 300, ImageFile with ID: 200, ImageFile with ID: 100]
*/
Run Code Online (Sandbox Code Playgroud)
如果集合中的元素类型不符合Comparable
协议,则必须使用sorted(by:)
以按升序或降序对元素进行排序.
class ImageFile: CustomStringConvertible {
let fileName: String
let fileID: Int
var description: String { return "ImageFile with ID: \(fileID)" }
init(fileName: String, fileID: Int) {
self.fileName = fileName
self.fileID = fileID
}
}
let images = [
ImageFile(fileName: "Car", fileID: 300),
ImageFile(fileName: "Boat", fileID: 100),
ImageFile(fileName: "Plane", fileID: 200)
]
let sortedImages = images.sorted(by: { (img0: ImageFile, img1: ImageFile) -> Bool in
return img0.fileID < img1.fileID
})
//let sortedImages = images.sorted { $0.fileID < $1.fileID } // also works
print(sortedImages)
/*
prints: [ImageFile with ID: 300, ImageFile with ID: 200, ImageFile with ID: 100]
*/
Run Code Online (Sandbox Code Playgroud)
需要注意的是斯威夫特还提供了两种方法称为sort()
与sort(by:)
作为同行sorted()
和sorted(by:)
,如果你需要到您的收藏就地进行排序.
jai*_*jan 23
在Swift 3.0中
images.sort(by: { (first: imageFile, second: imageFile) -> Bool in
first. fileID < second. fileID
})
Run Code Online (Sandbox Code Playgroud)
Ber*_*uer 18
两种选择
1)使用sortInPlace排序原始数组
self.assignments.sortInPlace({ $0.order < $1.order })
self.printAssignments(assignments)
Run Code Online (Sandbox Code Playgroud)
2)使用替代数组来存储有序数组
var assignmentsO = [Assignment] ()
assignmentsO = self.assignments.sort({ $0.order < $1.order })
self.printAssignments(assignmentsO)
Run Code Online (Sandbox Code Playgroud)
jnb*_*ard 18
斯威夫特2到4
原始答案试图使用某些属性对一组自定义对象进行排序.下面我将向您展示一些方便的方法来执行与快速数据结构相同的行为!
除了小事,我稍微改变了ImageFile.考虑到这一点,我创建了一个包含三个图像文件的数组.请注意,元数据是一个可选值,传递为nil作为参数是预期的.
struct ImageFile {
var name: String
var metadata: String?
var size: Int
}
var images: [ImageFile] = [ImageFile(name: "HelloWorld", metadata: nil, size: 256), ImageFile(name: "Traveling Salesmen", metadata: "uh this is huge", size: 1024), ImageFile(name: "Slack", metadata: "what's in this stuff?", size: 2048) ]
Run Code Online (Sandbox Code Playgroud)
ImageFile有一个名为size的属性.对于以下示例,我将向您展示如何使用具有大小等属性的排序操作.
最小到最大尺寸(<)
let sizeSmallestSorted = images.sorted { (initial, next) -> Bool in
return initial.size < next.size
}
Run Code Online (Sandbox Code Playgroud)
从最小到最小(>)
let sizeBiggestSorted = images.sorted { (initial, next) -> Bool in
return initial.size > next.size
}
Run Code Online (Sandbox Code Playgroud)
接下来,我们将使用String属性名称进行排序.以相同的方式,使用sort来比较字符串.但请注意内部块返回比较结果.此结果将定义排序.
AZ(.orderedAscending)
let nameAscendingSorted = images.sorted { (initial, next) -> Bool in
return initial.name.compare(next.name) == .orderedAscending
}
Run Code Online (Sandbox Code Playgroud)
ZA(.orderedDescending)
let nameDescendingSorted = images.sorted { (initial, next) -> Bool in
return initial.name.compare(next.name) == .orderedDescending
}
Run Code Online (Sandbox Code Playgroud)
接下来是我最喜欢的排序方式,在很多情况下,会有一个可选的属性.现在不用担心,我们将按照与上面相同的方式进行排序,除非我们必须处理nil!在生产中;
我使用此代码强制我的数组中的所有实例使用nil属性值为最后一个.然后使用假定的未包装值来排序元数据.
let metadataFirst = images.sorted { (initial, next) -> Bool in
guard initial.metadata != nil else { return true }
guard next.metadata != nil else { return true }
return initial.metadata!.compare(next.metadata!) == .orderedAscending
}
Run Code Online (Sandbox Code Playgroud)
可以对选项进行二次排序.例如; 可以显示带有元数据的图像并按大小排序.
Nic*_*nié 17
你也可以这样做
images = sorted(images) {$0.fileID > $1.fileID}
Run Code Online (Sandbox Code Playgroud)
所以你的图像数组将被存储为已排序
Gur*_*ngh 15
Swift 4.0,4.1和4.2首先,我创建了类型为imageFile()的可变数组,如下所示
var arr = [imageFile]()
Run Code Online (Sandbox Code Playgroud)
创建imageFile()类型的可变对象图像,并为属性赋值,如下所示
var image = imageFile()
image.fileId = 14
image.fileName = "A"
Run Code Online (Sandbox Code Playgroud)
现在,将此对象追加到数组arr
arr.append(image)
Run Code Online (Sandbox Code Playgroud)
现在,将不同的属性分配给相同的可变对象,即图像
image = imageFile()
image.fileId = 13
image.fileName = "B"
Run Code Online (Sandbox Code Playgroud)
现在,再次将图像对象追加到数组arr
arr.append(image)
Run Code Online (Sandbox Code Playgroud)
现在,我们将在数组arr对象的fileId属性上应用升序.使用<符号升序
arr = arr.sorted(by: {$0.fileId < $1.fileId}) // arr has all objects in Ascending order
print("sorted array is",arr[0].fileId)// sorted array is 13
print("sorted array is",arr[1].fileId)//sorted array is 14
Run Code Online (Sandbox Code Playgroud)
现在,我们将在数组arr对象的fileId属性上应用降序.使用>符号表示降序
arr = arr.sorted(by: {$0.fileId > $1.fileId}) // arr has all objects in Descending order
print("Unsorted array is",arr[0].fileId)// Unsorted array is 14
print("Unsorted array is",arr[1].fileId)// Unsorted array is 13
Run Code Online (Sandbox Code Playgroud)
在Swift 4.1中.&4.2对于分类订单使用
let sortedArr = arr.sorted { (id1, id2) -> Bool in
return id1.fileId < id2.fileId // Use > for Descending order
}
Run Code Online (Sandbox Code Playgroud)
McK*_*ley 14
如果数组元素符合Comparable
,那么您可以简单地使用函数语法:
array.sort(by: <)
Run Code Online (Sandbox Code Playgroud)
如果您根据自定义类型进行排序,您所需要做的就是实现<
运算符:
class ImageFile {
let fileName: String
let fileID: Int
let fileSize: Int
static func < (left: ImageFile, right: ImageFile) -> Bool {
return left.fileID < right.fileID
}
}
Run Code Online (Sandbox Code Playgroud)
但是,有时您不需要一种标准的比较方法ImageFile
。也许在某些情况下您希望根据 来对图像进行排序fileID
,而在其他情况下您希望根据 来对图像进行排序fileSize
。对于动态比较,您有两种选择。
sorted(by:)
images = images.sorted(by: { a, b in
// Return true if `a` belongs before `b` in the sorted array
if a.fileID < b.fileID { return true }
if a.fileID > b.fileID { return false }
// Break ties by comparing file sizes
return a.fileSize > b.fileSize
})
Run Code Online (Sandbox Code Playgroud)
您可以使用尾随闭包来简化语法:
images.sorted { ... }
Run Code Online (Sandbox Code Playgroud)
但是手动输入if
语句可能会导致代码很长(如果我们想通过根据文件名排序来打破文件大小的束缚,我们将面临一连串if
的厄运)。我们可以通过使用全新的SortComparator
协议(macOS 12+、iOS 15+)来避免这种语法:
sorted(using:)
files = files.sorted(using: [
KeyPathComparator(\.fileID, order: .forward),
KeyPathComparator(\.fileSize, order: .reverse),
])
Run Code Online (Sandbox Code Playgroud)
此代码根据文件 ID 对文件进行排序(.forward
表示升序),并根据文件大小进行排序(.reverse
表示降序)来打破平局。语法\.fileID
是我们指定关键路径的方式。您可以根据需要扩展比较器列表。
小智 10
您可以通过以下方式从 fileID 属性返回一个排序数组:
斯威夫特 2
let sortedArray = images.sorted({ $0.fileID > $1.fileID })
Run Code Online (Sandbox Code Playgroud)
斯威夫特 3 或 4
let sortedArray = images.sorted(by: { $0.fileID > $1.fileID })
Run Code Online (Sandbox Code Playgroud)
斯威夫特 5.0
let sortedArray = images.sorted {
$0.fileID < $1.fileID
}
Run Code Online (Sandbox Code Playgroud)
如果您要在多个位置对此数组进行排序,那么使您的数组类型可比较是有意义的.
class MyImageType: Comparable, Printable {
var fileID: Int
// For Printable
var description: String {
get {
return "ID: \(fileID)"
}
}
init(fileID: Int) {
self.fileID = fileID
}
}
// For Comparable
func <(left: MyImageType, right: MyImageType) -> Bool {
return left.fileID < right.fileID
}
// For Comparable
func ==(left: MyImageType, right: MyImageType) -> Bool {
return left.fileID == right.fileID
}
let one = MyImageType(fileID: 1)
let two = MyImageType(fileID: 2)
let twoA = MyImageType(fileID: 2)
let three = MyImageType(fileID: 3)
let a1 = [one, three, two]
// return a sorted array
println(sorted(a1)) // "[ID: 1, ID: 2, ID: 3]"
var a2 = [two, one, twoA, three]
// sort the array 'in place'
sort(&a2)
println(a2) // "[ID: 1, ID: 2, ID: 2, ID: 3]"
Run Code Online (Sandbox Code Playgroud)
如果您不使用自定义对象,而是使用值类型来实现Comparable协议(Int,String等..),您可以简单地执行此操作:
myArray.sort(>) //sort descending order
Run Code Online (Sandbox Code Playgroud)
一个例子:
struct MyStruct: Comparable {
var name = "Untitled"
}
func <(lhs: MyStruct, rhs: MyStruct) -> Bool {
return lhs.name < rhs.name
}
// Implementation of == required by Equatable
func ==(lhs: MyStruct, rhs: MyStruct) -> Bool {
return lhs.name == rhs.name
}
let value1 = MyStruct()
var value2 = MyStruct()
value2.name = "A New Name"
var anArray:[MyStruct] = []
anArray.append(value1)
anArray.append(value2)
anArray.sort(>) // This will sort the array in descending order
Run Code Online (Sandbox Code Playgroud)
斯威夫特 3,4,5
struct imageFile {
var fileName = String()
var fileID = Int()
}
//append objects like this
var arrImages = [imageFile]()
arrImages.append(.init(fileName: "Hello1.png", fileID: 1))
arrImages.append(.init(fileName: "Hello3.png", fileID: 3))
arrImages.append(.init(fileName: "Hello2.png",fileID: 2))
//array sorting using below code
let sortImagesArr = arrImages.sorted(by: {$0.fileID < $1.fileID})
print(sortImagesArr)
//output
imageFile(fileName: "Hello1.png", fileID: 1),
imageFile(fileName: "Hello2.png", fileID: 2),
imageFile(fileName: "Hello3.png", fileID: 3)
Run Code Online (Sandbox Code Playgroud)
我这样做并且有效:
var images = [imageFile]()
images.sorted(by: {$0.fileID.compare($1.fileID) == .orderedAscending })