Swift: จัดเรียงอาร์เรย์ของวัตถุตามตัวอักษร


145

ฉันมีสิ่งนี้:

class Movies {
  Name:String
  Date:Int
}

และชุด [ภาพยนตร์] ฉันจะจัดเรียงอาร์เรย์ตามตัวอักษรตามชื่อได้อย่างไร ฉันได้ลองแล้ว:

movieArr = movieArr.sorted{ $0 < $1 }

และ

movieArr = sorted(movieArr)

แต่ไม่ได้ผลเพราะฉันไม่ได้เข้าถึงแอตทริบิวต์ชื่อของ Movies

คำตอบ:


309

ในการปิดที่คุณส่งผ่านให้sortเปรียบเทียบคุณสมบัติที่คุณต้องการจัดเรียงตาม แบบนี้:

movieArr.sorted { $0.name < $1.name }

หรือต่อไปนี้ในกรณีที่คุณต้องการข้ามกรณี:

movieArr.sorted { $0.name.lowercased() < $1.name.lowercased() }

Sidenote:โดยทั่วไปแล้วประเภทจะเริ่มต้นด้วยตัวอักษรตัวพิมพ์ใหญ่เท่านั้น ผมขอแนะนำให้ใช้nameและdateไม่ได้และNameDate


ตัวอย่างในสนามเด็กเล่น:

class Movie {
    let name: String
    var date: Int?

    init(_ name: String) {
        self.name = name
    }
}

var movieA = Movie("A")
var movieB = Movie("B")
var movieC = Movie("C")

let movies = [movieB, movieC, movieA]
let sortedMovies = movies.sorted { $0.name < $1.name }
sortedMovies

sortedMovies จะอยู่ในลำดับ [movieA, movieB, movieC]

อัปเดต Swift5

channelsArray = channelsArray.sorted { (channel1, channel2) -> Bool in
            let channelName1 = channel1.name
            let channelName2 = channel2.name
            return (channelName1.localizedCaseInsensitiveCompare(channelName2) == .orderedAscending)

ขอบคุณฉันเพิ่งเริ่มใช้ Swift และฉันไม่รู้เกี่ยวกับการใช้การปิด
cdpalmer

1
ใช้ movies.sort แทนภาพยนตร์สารพัน @Mike S
Oskariagon

1
ขอบคุณสำหรับคำอธิบาย ปรับปรุงการแก้ไขของฉันควรจะดีโปรดดู :)
Julian Król

9
ระวังสิ่งนี้จะไม่ทำงานเมื่อจัดเรียงสตริงที่อาจเป็นตัวพิมพ์ใหญ่หรือไม่ก็ได้ การเปรียบเทียบ.lowercaseStringจะช่วยแก้ปัญหานี้
Matthieu Riegler

2
@EricAya หมายเหตุมันอยู่sortedใน Swift 3 อีกครั้ง: D.
dvp.petrov

47

ด้วย Swift 3 คุณสามารถเลือกหนึ่งในวิธีต่อไปนี้เพื่อแก้ปัญหาของคุณ


1. ใช้sorted(by:​)กับMovieคลาสที่ไม่เป็นไปตามComparableโปรโตคอล

หากMovieคลาสของคุณไม่เป็นไปตามComparableโปรโตคอลคุณต้องระบุในการปิดคุณสมบัติที่คุณต้องการใช้sorted(by:​)เมธอดของ Array

Movie การประกาศคลาส:

import Foundation

class Movie: CustomStringConvertible {

    let name: String
    var date: Date
    var description: String { return name }

    init(name: String, date: Date = Date()) {
        self.name = name
        self.date = date
    }

}

การใช้งาน:

let avatarMovie = Movie(name: "Avatar")
let titanicMovie = Movie(name: "Titanic")
let piranhaMovie = Movie(name: "Piranha II: The Spawning")

let movies = [avatarMovie, titanicMovie, piranhaMovie]
let sortedMovies = movies.sorted(by: { $0.name < $1.name })
// let sortedMovies = movies.sorted { $0.name < $1.name } // also works

print(sortedMovies)

/*
prints: [Avatar, Piranha II: The Spawning, Titanic]
*/

2. ใช้sorted(by:​)กับMovieคลาสที่สอดคล้องกับComparableโปรโตคอล

อย่างไรก็ตามการทำให้Movieคลาสของคุณเป็นไปตามComparableโปรโตคอลคุณสามารถมีโค้ดที่กระชับมากเมื่อคุณต้องการใช้sorted(by:​)เมธอดของ Array

Movie การประกาศคลาส:

import Foundation

class Movie: CustomStringConvertible, Comparable {

    let name: String
    var date: Date
    var description: String { return name }

    init(name: String, date: Date = Date()) {
        self.name = name
        self.date = date
    }

    static func ==(lhs: Movie, rhs: Movie) -> Bool {
        return lhs.name == rhs.name
    }

    static func <(lhs: Movie, rhs: Movie) -> Bool {
        return lhs.name < rhs.name
    }

}

การใช้งาน:

let avatarMovie = Movie(name: "Avatar")
let titanicMovie = Movie(name: "Titanic")
let piranhaMovie = Movie(name: "Piranha II: The Spawning")

let movies = [avatarMovie, titanicMovie, piranhaMovie]
let sortedMovies = movies.sorted(by: { $0 < $1 })
// let sortedMovies = movies.sorted { $0 < $1 } // also works
// let sortedMovies = movies.sorted(by: <) // also works

print(sortedMovies)

/*
 prints: [Avatar, Piranha II: The Spawning, Titanic]
 */

3. ใช้sorted()กับMovieคลาสที่สอดคล้องกับComparableโปรโตคอล

โดยการทำให้คุณMovieระดับสอดคล้องกับComparableโปรโตคอลคุณสามารถใช้อาร์เรย์ของวิธีการเป็นทางเลือกให้กับsorted()sorted(by:​)

Movie การประกาศคลาส:

import Foundation

class Movie: CustomStringConvertible, Comparable {

    let name: String
    var date: Date
    var description: String { return name }

    init(name: String, date: Date = Date()) {
        self.name = name
        self.date = date
    }

    static func ==(lhs: Movie, rhs: Movie) -> Bool {
        return lhs.name == rhs.name
    }

    static func <(lhs: Movie, rhs: Movie) -> Bool {
        return lhs.name < rhs.name
    }

}

การใช้งาน:

let avatarMovie = Movie(name: "Avatar")
let titanicMovie = Movie(name: "Titanic")
let piranhaMovie = Movie(name: "Piranha II: The Spawning")

let movies = [avatarMovie, titanicMovie, piranhaMovie]
let sortedMovies = movies.sorted()

print(sortedMovies)

/*
 prints: [Avatar, Piranha II: The Spawning, Titanic]
 */

เฮ้มีความแตกต่างหรือไม่ ระหว่างวันที่ 2 และ 3 (ยกเว้นmovies.sorted(by: <)และmovies.sorted())?
Kamaldeep singh Bhatia

sorted(by:)และsorted()เป็นสองวิธีที่แตกต่างกัน คุณสามารถใช้array.sorted()เป็นทางเลือกสำหรับarray.sorted(by: <).
Imanou Petit

ใช่แค่ถามในกรณีที่มีการกำหนดคลาสเราจำเป็นต้องเปลี่ยนแปลงอะไรไหม? ฉันหมายความว่าเราสามารถกำหนดคลาสเดียวกันสำหรับทั้งคู่sorted(by:)และsorted()?
Kamaldeep singh Bhatia

1
ได้คุณสามารถนำคลาส / โครงสร้างของคุณไปใช้แบบเดียวกันซึ่งไม่ว่าในกรณีใด ๆ จะต้องเป็นไปตามComparableโปรโตคอล
Imanou Petit

ฉันมี Array กับ customObject เมื่อฉันเลือกลำดับจากน้อยไปมากมันไม่ได้ทำให้สั้นลงอย่างเหมาะสม "1" "14""28""31""4""42""49"
Krunal Nagvadia

17
let sortArray =  array.sorted(by: { $0.name.lowercased() < $1.name.lowercased() })

การเพิ่ม. lowercased () ได้ผลสำหรับฉันหลังจากพยายามมานาน ฉันไม่เข้าใจว่าทำไมเนื่องจากข้อความทั้งหมดถูกลดขนาดลงเพื่อเริ่มต้นด้วย
Tom Tallak Solbu

เมื่อใช้ lowercased () จะเปลี่ยนชื่อทั้งหมดเป็นตัวพิมพ์เล็กเพื่อเรียงลำดับอย่างถูกต้อง :)
m.alqadi


1

เรียงลำดับอาร์เรย์ Swift 4.2

arrayOfRaces = arrayOfItems.sorted(by: { ($0["raceName"] as! String) < ($1["raceName"] as! String) })

0
*import Foundation
import CoreData


extension Messages {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Messages> {
        return NSFetchRequest<Messages>(entityName: "Messages")
    }

    @NSManaged public var text: String?
    @NSManaged public var date: Date?
    @NSManaged public var friends: Friends?

}

    //here arrMessage is the array you can sort this array as under bellow 

    var arrMessages = [Messages]()

    arrMessages.sort { (arrMessages1, arrMessages2) -> Bool in
               arrMessages1.date! > arrMessages2.date!
    }*

0

คำตอบเหล่านี้ส่วนใหญ่ผิดเนื่องจากความล้มเหลวในการใช้การเปรียบเทียบตามสถานที่สำหรับการเรียงลำดับ ดูที่ localizedStandardCompare ()

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.