быстрая сортировка массива объектов [дубликат]

Используя функцию merge и ее необязательные параметры:

Внутреннее соединение: merge(df1, df2) будет работать для этих примеров, поскольку R автоматически присоединяется к кадрам по именам общих переменных , но вы, скорее всего, захотите указать merge(df1, df2, by = "CustomerId"), чтобы убедиться, что вы соответствуете только по желаемым полям. Вы также можете использовать параметры by.x и by.y, если соответствующие переменные имеют разные имена в разных кадрах данных.

Внешнее соединение: merge(x = df1, y = df2, by = "CustomerId", all = TRUE)

Левый внешний: merge(x = df1, y = df2, by = "CustomerId", all.x = TRUE)

Правый внешний: merge(x = df1, y = df2, by = "CustomerId", all.y = TRUE)

Крест: merge(x = df1, y = df2, by = NULL)

Как и с внутренним соединением, вы, вероятно, захотите явно передать «CustomerId» в R в качестве сопоставимой переменной. Я думаю, что почти всегда лучше указывать идентификаторы, с которыми вы хотите объединиться; это безопаснее, если входные данные.кадры меняются неожиданно и легче читать позже.

Вы можете объединить несколько столбцов, указав by вектор, например, by = c("CustomerId", "OrderId").

Если имена столбцов для объединения не совпадают, вы можете указать, например, by.x = "CustomerId_in_df1", by.y = "CustomerId_in_df2" where CustomerId_in_df1 is the name of the column in the first data frame and CustomerId_in_df2` - это имя столбца во втором кадре данных. (Они также могут быть векторами, если вам нужно объединить несколько столбцов.)

353
задан mohacs 9 June 2014 в 23:27
поделиться

15 ответов

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

var images : [imageFile] = []

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

Swift 2

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

Swift 3 & amp; 4

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

В приведенном выше примере указан порядок сортировки по порядку

655
ответ дан Lepidopteron 21 August 2018 в 10:36
поделиться
  • 1
    Мне не хватает части объявления массива, это сделал трюк Array & lt; imageFile & gt ;. – mohacs 9 June 2014 в 23:44
  • 2
    @AlexWayne У меня есть подкласс NSManagedObject под названием CheckInAndOut . И в отдельном файле я объявлял типизированный массив для объектов этого типа, и когда я пытаюсь sort , я получаю Не могу найти ошибку члена . Любая идея, почему это так? – Isuru 28 September 2014 в 17:34
  • 3
    Я нашел свою проблему. По-видимому, массив не был типизированным массивом. Во всяком случае, у меня новая проблема. Как я могу отсортировать массив по нескольким свойствам? Скажем, у меня есть 2 свойства, такие как firstName и lastName в массиве объектов Person. Сначала я хочу отсортировать его по firstName, а затем lastName. Как я могу это сделать? – Isuru 10 November 2014 в 19:02
  • 4
    вам теперь нужно делать images.sortInPlace({ $0.fileID > $1.fileID })? – Taylor M 30 September 2015 в 21:21
  • 5
    в случае, если кто-то задается вопросом то же самое: ответ даст desc order – Danny Wang 4 April 2016 в 07:21

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

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)
17
ответ дан Bernauer 21 August 2018 в 10:36
поделиться
  • 1
    re 2) Какой смысл в создании пустого массива и отбрасывании его в следующей строке? Я использовал бы sugest с помощью var assignmentsO : [Assignment] или объединил его в одну строку, используя let assignmentsO = self.assignments.sort({ $0.order < $1.order }) – Hermann Klecker 23 January 2016 в 00:35
  • 2

Если вы не используете пользовательские объекты, а вместо этого вместо типов значений реализуете протокол 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
5
ответ дан dorian 21 August 2018 в 10:36
поделиться

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

вы можете использовать методы экземпляра 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 })

Для разработки объяснение о принципе работы, см. Сортированная функция .

47
ответ дан fujianjin6471 21 August 2018 в 10:36
поделиться

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

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)
181
ответ дан GoZoner 21 August 2018 в 10:36
поделиться
  • 1
    как я могу подать в суд на это со строкой? Мне нужно сортировать строку по ее длине – Muneef M 28 November 2015 в 21:57
  • 2
    @MuneefM просто возвращает string1.length & lt; string2.length – commando24 30 August 2016 в 10:33
  • 3
    sort больше не компилируется с этим синтаксисом в Xcode 8. Xcode 8 говорит, что $0.fileID < $1.fileID создает Bool not ComparisonResult. – Crashalot 24 September 2016 в 08:46
  • 4
    Этот код ответа отлично работает в Xcode8; если у вас есть ошибка, отправьте новый вопрос. – GoZoner 24 September 2016 в 14:54

Swift 4.0. Во-первых, я создал измененный массив типа imageFile (), как показано ниже

var arr = [imageFile]()

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

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

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

    arr.append(image)

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

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

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

    arr.append(image)

Теперь мы применим Ascending order по свойству fileId в объектах array arr. Используйте & lt; символ для возрастания

 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

Теперь мы применим Descending order on в свойстве fileId в объектах array 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. Для отсортированного заказа используйте

let sortedArr = arr.sorted { (id1, id2) -> Bool in
  return id1.fileId < id2.fileId // Use > for Descending order
}
6
ответ дан Gurjinder Singh Khalsa 21 August 2018 в 10:36
поделиться
2
ответ дан Hanny 21 August 2018 в 10:36
поделиться

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

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

0
ответ дан Illya Krit 21 August 2018 в 10:36
поделиться

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

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

func sorted() -> [Element]

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

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

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

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

Если тип элемента внутри вашей коллекции соответствует протоколу Comparable, вы сможете использовать sorted() для сортировки ваших элементов с возрастающим порядком. Следующий код игровой площадки показывает, как использовать 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:), если вам нужно сортировать свою коллекцию на месте.

15
ответ дан Imanou Petit 21 August 2018 в 10:36
поделиться
22
ответ дан jaiswal Rajan 21 August 2018 в 10:36
поделиться

Swift с 2 по 4

Исходный ответ искал сортировку массива пользовательских объектов с использованием некоторого свойства. Ниже я покажу вам несколько удобных способов сделать то же самое поведение с быстрыми структурами данных!

Мало что уходит в путь, я немного изменил ImageFile. Имея это в виду, я создаю массив с тремя файлами изображений. Обратите внимание, что метаданные являются необязательным значением, проходящим в нуле, поскольку ожидается ожидаемый параметр.

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

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

от самого маленького до самого большого размера (& lt;)

    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. Аналогичным образом используйте сортировку для сравнения строк. Но обратите внимание, что внутренний блок возвращает результат сравнения. Этот результат определит sort.

AZ (.orderedAscending)

    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
    }

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

9
ответ дан jnblanchard 21 August 2018 в 10:36
поделиться
  • 1
    Как правило, ответы гораздо полезнее, если они включают объяснение того, что должен делать код, и почему это решает проблему, не представляя других. – Tom Aranda 19 December 2017 в 06:03
  • 2
    @TomAranda спасибо, надеюсь, это помогает другим. – jnblanchard 19 December 2017 в 16:50
  • 3
    Намного лучше. – Tom Aranda 19 December 2017 в 17:01
var students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]

students.sort(by: >)

print(students)

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

1
ответ дан K.Dᴀᴠɪs 21 August 2018 в 10:36
поделиться

Если вы собираетесь сортировать этот массив в нескольких местах, может возникнуть смысл сделать ваш тип массива 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]"
6
ответ дан kwerle 21 August 2018 в 10:36
поделиться

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

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

, чтобы ваш массив изображений был сохранен как отсортированный

15
ответ дан Pascal 21 August 2018 в 10:36
поделиться

Swift 3

people = people.sorted(by: { $0.email > $1.email })
38
ответ дан quemeful 21 August 2018 в 10:36
поделиться
  • 1
    я пробовал это с сопоставлением даты, не мог заставить его работать. Есть идеи? – Ebru Güngör 20 November 2016 в 22:29
  • 2
  • 3
    Не NSDate или String, текущий swift 3 Объект Date. – Ebru Güngör 20 November 2016 в 23:42
  • 4
    Какое свойство Date вы сравниваете? Свойство должно быть сопоставимо с используемой функцией (больше, чем в моем примере) – quemeful 20 November 2016 в 23:46
  • 5
    Это единственный полезный ответ на 2017 год. – Fattie 3 January 2017 в 17:24
Другие вопросы по тегам:

Похожие вопросы: