programing

Swift에서 속성 값을 기준으로 사용자 지정 개체 배열을 정렬하는 방법

i4 2023. 5. 16. 22:09
반응형

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)

'파일별로 이미지 배열을 정렬하려면 어떻게 해야 합니까?아이디는 오름차순? 내림차순?

먼저, 다음을 반복할 때 메소드를 호출할 수 있도록 배열을 입력된 배열로 선언합니다.

var images : [imageFile] = []

그러면 간단하게 다음을 수행할 수 있습니다.

스위프트 2

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

스위프트 3

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

스위프트 5

images.sorted { $0.fileId > $1.fileID }

위의 예제는 결과를 내림차순으로 제공합니다.

[Swift 3에 대해 정렬(: 기준)로 업데이트됨]이는 후행 폐쇄를 이용하는 것입니다.

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

을 하는 곳<또는>각각 ASC 또는 DESC에 따라 달라집니다.배열을 수정하려면 다음을 사용합니다.

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

이 작업을 반복하고 함수를 정의하려는 경우 한 가지 방법은 다음과 같습니다.

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

다음과 같이 사용합니다.

images.sort(by: sorterForFileIDASC)

스위프트 3

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

스위프트 5와 함께라면,Array와 라고 하는 두 가지 방법이 있습니다.첫 번째 방법은,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는 또한 와 의 대응물로 불리는 두 가지 방법을 제공합니다.sorted()그리고.sorted(by:)수집품을 제자리에 정렬해야 하는 경우.

거의 모든 사람이 직접적으로 설명합니다. 진화 과정을 보여드리겠습니다.

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

정렬의 작동 원리에 대한 자세한 설명은 정렬 함수를 참조하십시오.

Swift 3.0에서

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

당신은 또한 다음과 같은 것을 할 수 있습니다.

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

이미지 배열이 정렬된 상태로 저장됩니다.

Swift 4.0, 4.1 및 4.2:

먼저 유형의 가변 배열을 만들었습니다.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)

이제 배열의 속성에 오름차순을 적용하겠습니다.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

이제 배열의 속성에 내림차순을 적용하겠습니다.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
}

스위프트 2 ~ 4

원래 답변은 일부 속성을 사용하여 사용자 지정 개체 배열을 정렬하려고 했습니다.아래에서 빠른 데이터 구조로 동일한 동작을 수행하는 몇 가지 유용한 방법을 보여드리겠습니다!

작은 일들로 인해, 저는 ImageFile을 아주 조금 바꿨습니다.이를 염두에 두고 이미지 파일 3개로 배열을 만듭니다.메타데이터는 선택적 값이며 매개 변수가 예상되는 대로 0으로 전달됩니다.

 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라는 속성이 있습니다.다음 예제에서는 크기와 같은 속성을 가진 정렬 작업을 사용하는 방법을 보여드리겠습니다.

가장 작은 것부터 가장 큰 것까지 (<)

    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 속성 이름을 사용하여 정렬하겠습니다.마찬가지로 정렬을 사용하여 문자열을 비교합니다.그러나 내부 블록은 비교 결과를 반환합니다.이 결과는 정렬을 정의합니다.

A-Z(.순서 상승)

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

Z-A(.순서 내림차순서

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

다음은 제가 가장 좋아하는 정렬 방법입니다. 대부분의 경우 선택적 속성이 있습니다.이제 걱정하지 마십시오. 위와 같은 방식으로 정렬할 것입니다. 단, 0을 처리해야 합니다.생산 중;

이 코드를 사용하여 속성 값이 0인 배열의 모든 인스턴스를 마지막으로 지정했습니다.그런 다음 랩핑되지 않은 가정된 값을 사용하여 메타데이터를 정렬합니다.

    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
    }

선택사항에 대한 보조 정렬이 가능합니다.예를 들어 메타데이터가 포함된 이미지를 크기별로 정렬하여 표시할 수 있습니다.

두 가지 대안

sortInPlace를 사용하여 원래 배열 순서 지정

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

대체 배열을 사용하여 정렬된 배열 저장

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

파일에서 정렬된 배열을 반환합니다.다음 방법을 통한 ID 속성:

스위프트 2

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

스위프트 3 OR 4

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

스위프트 5.0

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

이 배열을 둘 이상의 위치에서 정렬하려는 경우 배열 유형을 비교 가능하게 만드는 것이 적절할 수 있습니다.

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

사용자 지정 개체를 사용하지 않고 비교 가능한 프로토콜(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

배열 요소가 다음을 준수하는 경우 기능 구문을 사용하면 됩니다.

array.sort(by: <)

사용자 정의 유형을 기준으로 정렬하는 경우 다음을 구현하기만 하면 됩니다.<연산자:

class ImageFile {
    let fileName: String
    let fileID: Int
    let fileSize: Int
    static func < (left: ImageFile, right: ImageFile) -> Bool {
        return left.fileID < right.fileID
    }
}

하지만, 때때로 당신은 한 가지 표준적인 비교 방법을 원하지 않을 때가 있습니다.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
})

후행 마감을 사용하여 구문을 단순화할 수 있습니다.

images.sorted { ... }

하지만 수동으로 입력하는 것은if문은 긴 코드로 이어질 수 있습니다. (만약 우리가 파일 이름을 기준으로 정렬함으로써 파일 크기 연결을 끊으려면, 우리는 꽤 많은if운명의 연쇄)최신 프로토콜(macOS 12+, iOS 15+)을 사용하면 이러한 구문을 피할 수 있습니다.

sorted(using:)

files = files.sorted(using: [
    KeyPathComparator(\.fileID, order: .forward),
    KeyPathComparator(\.fileSize, order: .reverse),
])

파일 ID)를 을 정렬합니다..forward하며, 파일 으)로 ..reverse내림을 의미합니다.\.fileID구문은 키 경로를 지정하는 방법입니다.비교기 목록을 필요한 만큼 확장할 수 있습니다.

스위프트 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)

이렇게 하면 효과가 있습니다.

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

사용자 지정 개체의 원래 배열을 정렬하려는 경우.Swift 2.1에서 이를 수행하는 다른 방법이 있습니다.

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

에▁where디id정수입니다.동일하게 사용할 수 있습니다.<의 연산자입니다.String자산도 마찬가지입니다.

사용에 대한 자세한 내용은 여기 예를 참조하십시오. Swift2: 인근 고객

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

students.sort(by: >)

print(students)

인쇄:"["Peter", "Kweku", "Kofi", "Akosua", "Abena"]"

키 경로를 사용하여 정렬

기준으로 정렬할 수 있습니다.KeyPath다음과 같이:

myArray.sorted(by: \.fileName, <) /* using `<` for ascending sorting */

이 작은 도움이 되는 확장을 구현함으로써.

extension Collection{
    func sorted<Value: Comparable>(
        by keyPath: KeyPath<Element, Value>,
        _ comparator: (_ lhs: Value, _ rhs: Value) -> Bool) -> [Element] {
        sorted { comparator($0[keyPath: keyPath], $1[keyPath: keyPath]) }
    }
}

Swift가 가까운 미래에 이것을 언어의 핵심에 추가하기를 바랍니다.

스위프트 3 & 4 & 5

소문자와 대문자와 관련된 문제가 있었습니다.

그래서 이 코드를 만들었습니다.

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

그런 다음 정렬된 이미지를 사용합니다.

언급URL : https://stackoverflow.com/questions/24130026/how-to-sort-an-array-of-custom-objects-by-property-value-in-swift

반응형