Подтвердить что ты не робот

Swift, как сортировать массив настраиваемых объектов по значению свойства

позволяет сказать, что у нас есть собственный класс с именем imageFile, и этот класс содержит два свойства.

class imageFile  {
    var fileName = String()
    var fileID = Int()
}

многие из них хранятся в массиве

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)
Вопрос

: как я могу сортировать массив изображений с помощью 'fileID' ASC или DESC?

4b9b3361

Ответ 1

Сначала объявите ваш Array как типизированный массив, чтобы вы могли вызывать методы при выполнении итерации:

var images : [imageFile] = []

Тогда вы можете просто сделать:

Swift 2

images.sorted({ $0.fileID > $1.fileID })

Свифт 3 и Свифт 4 и Свифт 5

images.sorted(by: { $0.fileID > $1.fileID })

Пример выше дает порядок сортировки desc

Ответ 2

[Обновлено для Swift 3 с сортировкой (по:)] Это, используя замыкающее закрытие:

images.sorted { $0.fileID < $1.fileID }

где вы используете < или > в зависимости от ASC или DESC, соответственно. Если вы хотите изменить массив images, используйте следующее:

images.sort { $0.fileID < $1.fileID }

Если вы собираетесь делать это несколько раз и предпочитаете определять функцию, один из способов:

func sorterForFileIDASC(this:imageFile, that:imageFile) -> Bool {
  return this.fileID > that.fileID
}

а затем используйте как:

images.sort(by: sorterForFileIDASC)

Ответ 3

Почти каждый дает, как напрямую, позвольте мне показать эволюцию:

вы можете использовать методы экземпляра массива:

// general form of closure
images.sortInPlace({ (image1: imageFile, image2: imageFile) -> Bool in return image1.fileID > image2.fileID })

// types of closure 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 argument list along with "in" keyword can be omitted, $0, $1, $2, and so on are used to refer the closure 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 })

Подробное объяснение принципа работы сортировки см. Отсортированная функция.

Ответ 4

Swift 3

people = people.sorted(by: { $0.email > $1.email })

Ответ 5

В Swift 5 у Array есть два метода: sorted() и sorted(by:). Первый метод, sorted(), имеет следующее объявление:

Возвращает отсортированные элементы коллекции.

func sorted() -> [Element]

Второй метод, sorted(by:), имеет следующее объявление:

Возвращает элементы коллекции, отсортированные с использованием данного предиката в качестве сравнения между элементами.

func sorted(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> [Element]

# 1. Сортировка по возрастанию для сопоставимых объектов

Если тип элемента в вашей коллекции соответствует протоколу 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]
 */

# 2. Сортировка по убыванию для сопоставимых объектов

Если тип элемента в вашей коллекции соответствует протоколу 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]
 */

# 3. Сортировка по возрастанию или убыванию для несопоставимых объектов

Если тип элемента внутри вашей коллекции НЕ соответствует протоколу 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]
 */

Обратите внимание, что Swift также предоставляет два метода с именами sort() и sort(by:) в качестве аналогов sorted() и sorted(by:), если вам нужно отсортировать коллекцию на месте.

Ответ 6

В Swift 3.0

images.sort(by: { (first: imageFile, second: imageFile) -> Bool in
    first. fileID < second. fileID
})

Ответ 7

Вы также можете сделать что-то вроде

images = sorted(images) {$0.fileID > $1.fileID}

поэтому ваш массив изображений будет сохранен как отсортированный

Ответ 8

Две альтернативы

1) Заказ исходного массива с помощью sortInPlace

self.assignments.sortInPlace({ $0.order < $1.order })
self.printAssignments(assignments)

2) Использование альтернативного массива для хранения упорядоченного массива

var assignmentsO = [Assignment] ()
assignmentsO = self.assignments.sort({ $0.order < $1.order })
self.printAssignments(assignmentsO)

Ответ 9

Свифт с 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 in this stuff?", size: 2048) ]

ImageFile имеет свойство с именем size. В следующих примерах я покажу вам, как использовать операции сортировки с такими свойствами, как размер.

от меньшего к большему размеру (<)

    let sizeSmallestSorted = images.sorted { (initial, next) -> Bool in
      return initial.size < next.size
    }

от самого большого до самого маленького (>)

    let sizeBiggestSorted = images.sorted { (initial, next) -> Bool in
      return initial.size > next.size
    }

Далее мы отсортируем, используя имя свойства String. Таким же образом используйте сортировку для сравнения строк. Но обратите внимание, внутренний блок возвращает результат сравнения. Этот результат будет определять сортировку.

AZ (.orded Ascending)

    let nameAscendingSorted = images.sorted { (initial, next) -> Bool in
      return initial.name.compare(next.name) == .orderedAscending
    }

ZA (.orderedDescending)

    let nameDescendingSorted = images.sorted { (initial, next) -> Bool in
      return initial.name.compare(next.name) == .orderedDescending
    }

Далее мой любимый способ сортировки, во многих случаях у каждого будут дополнительные свойства. Теперь не волнуйтесь, мы будем сортировать так же, как описано выше, за исключением того, что мы должны обрабатывать ноль! В производстве;

Я использовал этот код, чтобы заставить все экземпляры в моем массиве со значениями свойства 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
    }

Для дополнительных опций возможна вторичная сортировка. Например; можно показать изображения с метаданными и упорядочить по размеру.

Ответ 10

Swift 4.0, 4.1 и 4.2 Сначала я создал изменяемый массив типа imageFile(), как показано ниже

var arr = [imageFile]()

Создайте изображение изменяемого объекта типа imageFile() и присвойте значение свойствам, как показано ниже

   var image = imageFile()
   image.fileId = 14
   image.fileName = "A"

Теперь добавьте этот объект в массив

    arr.append(image)

Теперь присвойте разные свойства одному и тому же изменяемому объекту, т.е. изображению

   image = imageFile()
   image.fileId = 13
   image.fileName = "B"

Теперь снова добавьте объект изображения в массив

    arr.append(image)

Теперь мы применим восходящий порядок для свойства fileId в массиве arr объектов. Использовать символ < в порядке возрастания

 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

Теперь мы применим порядок по убыванию для свойства fileId в массиве arr. Используйте символ> для сортировки по убыванию

 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

В Swift 4.1. & 4.2 Для отсортированного заказа используйте

let sortedArr = arr.sorted { (id1, id2) -> Bool in
  return id1.fileId < id2.fileId // Use > for Descending order
}

Ответ 11

Если вы собираетесь сортировать этот массив в нескольких местах, может возникнуть смысл сделать тип массива Comparable.

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]"

Ответ 12

Если вы не используете пользовательские объекты, а вместо этого вместо типов значений реализуете протокол Comparable (Int, String и т.д.), вы можете просто сделать это:

myArray.sort(>) //sort descending order

Пример:

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

Ответ 13

Я делаю это так и работает:

var images = [imageFile]() images.sorted(by: {$0.fileID.compare($1.fileID) == .orderedAscending })

Ответ 14

Если вы хотите отсортировать исходный массив пользовательских объектов. Вот еще один способ сделать это в Swift 2.1

var myCustomerArray = [Customer]()
myCustomerArray.sortInPlace {(customer1:Customer, customer2:Customer) -> Bool in
    customer1.id < customer2.id
}

Где id - целое число. Вы можете использовать тот же оператор < для свойств String.

Вы можете узнать больше о его использовании, посмотрев пример: Swift2: Клиенты поблизости

Ответ 15

var students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]

students.sort(by: >)

print(students)

Отпечатки: "["Peter", "Kweku", "Kofi", "Akosua", "Abena"]"

Ответ 16

Вы возвращаете отсортированный массив из свойства fileID следующим образом:

Swift 2

let sortedArray = images.sorted({ $0.fileID > $1.fileID })

Свифт 3 ИЛИ 4

let sortedArray = images.sorted(by: { $0.fileID > $1.fileID })

Swift 5.0

let sortedArray = images.sorted {
    $0.fileID < $1.fileID
}

Ответ 17

Свифт 3 и 4 и 5

У меня была проблема, связанная со строчными и прописными буквами

поэтому я сделал этот код

let sortedImages = images.sorted(by: { $0.fileID.lowercased() < $1.fileID.lowercased() })

а затем использовать sortedImages после этого