Swift:オブジェクトの配列をアルファベット順に並べ替え


136

私はこれを持っています:

class Movies {
  Name:String
  Date:Int
}

[映画]の配列。配列を名前のアルファベット順に並べ替える方法を教えてください。私はもう試した:

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

そして

movieArr = sorted(movieArr)

しかし、Moviesのname属性にアクセスしていないため、これは機能しません。

回答:


295

に渡すクロージャでsort、並べ替えに使用するプロパティを比較します。このような:

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

または、ケースをバイパスする場合は次のようにします。

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

補足:通常、タイプは大文字で始まるだけです。nameand dateではなくNameand を使用することをお勧めしDateます。


例、遊び場で:

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 2015年

1
movies.sortedの代わりにmovies.sortを使用する@Mike S
Oskariagon 2015年

1
説明してくれてありがとう。私の編集を改善しました、大丈夫です、見てください:)
JulianKrólDec

8
大文字と小文字を区別する文字列を並べ替える場合、これは機能しません。を比較すると、.lowercaseStringこの問題は解決します。
Matthieu

2
@EricAyaそれがsorted再びSwift 3にあることに注意してください:D。
dvp.petrov 16

44

Swift 3では、問題を解決するために次のいずれかの方法を選択できます。


1.使用sorted(by:​)してMovieに準拠していないクラスComparableのプロトコル

MovieクラスがComparableプロトコルに準拠していない場合は、Arrayのsorted(by:​)メソッドを使用するプロパティをクロージャーで指定する必要があります。

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プロトコルに準拠させることで、Arrayの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(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 2017

sorted(by:)sorted()は2つの異なる方法です。のarray.sorted()代替として使用できますarray.sorted(by: <)
Imanou Petit 2017

はい、クラス定義の場合に尋ねるだけで、何かを変更する必要がありますか?私が意味する、私たちは、両方に同じクラス定義を持つことができるsorted(by:)sorted()
Kamaldeep singh Bhatia

1
はい、クラス/構造体の実装を同じにすることができComparableます。どの実装でも、プロトコルに準拠する必要があります。
Imanou Petit 2017

昇順に並べると、customObjectの配列があり、適切な方法で短絡されていません。 "1" "14""28""31""4""42""49"
Krunal Nagvadia

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

.lowercased()を追加すると、長い間試してみました。最初はすべてのテキストが小文字だったので、なぜかわかりません。
トムタラックソルブ2018

lowercased()を使用すると、すべての名前が小文字に変更され、適切にソートされます:)
m.alqadi

14

Swift 3を使用しているユーザーの場合、受け入れられた回答の同等の方法は次のとおりです。

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

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!
    }*
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.