web-dev-qa-db-ja.com

配列内のオブジェクトを日付で並べ替える

HistoryObjectというオブジェクトを含む配列があり、「date」、「name」などのプロパティがあります。

私はそのように配列をソートしています:

 let sortedArray = HistoryArray.sort({ $0.date.compare($1.date) == NSComparisonResult.OrderedDescending})

これは、日付を新しいものから古いものにソートすることになっています。例えば:

  • 2016年6月30日
  • 2016年6月29日

等..

しかし、私の配列に「2016年7月2日」が含まれている場合、ソートされた配列は次のようになります。

  • 2016年6月30日
  • 2016年6月29日
  • 2016年7月2日

「2016年7月2日」はソート後に一番上に表示されるはずですが、今は一番下に表示されていますか?この問題を修正するにはどうすればよいですか?

38
Nata Mio

Swift 4およびSwift 3を使用

let testArray = ["25 Jun, 2016", "30 Jun, 2016", "28 Jun, 2016", "2 Jul, 2016"]
var convertedArray: [Date] = []

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd MM, yyyy"// yyyy-MM-dd"

for dat in testArray {
    let date = dateFormatter.date(from: dat)
    if let date = date {
        convertedArray.append(date)
    }
}

var ready = convertedArray.sorted(by: { $0.compare($1) == .orderedDescending })

print(ready)

Swift 2を使用

たとえば、日付と別の1つの配列を持つ配列があり、変換された日付を保存します。

var testArray = ["25 Jun, 2016", "30 Jun, 2016", "28 Jun, 2016", "2 Jul, 2016"]
var convertedArray: [NSDate] = []

その後、日付を変換します。

var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd MM, yyyy"// yyyy-MM-dd"

for dat in testArray {
    var date = dateFormatter.dateFromString(dat)
    convertedArray.append(date!)
}

そして結果:

var ready = convertedArray.sort({ $0.compare($1) == .OrderedDescending })

print(ready)
75
Altimir Antonov

For Swift

var testArray = ["25 Jun, 2016", "30 Jun, 2016", "28 Jun, 2016", "2 Jul, 2016"]
var convertedArray: [Date] = []

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"

for dat in testArray {
    var date = dateFormatter.date(from: dat)
    convertedArray.append(date!)
}

//Approach : 1
convertedArray.sort(){$0 < $1}    

//Approach : 2
convertedArray.sorted(by: {$0.timeIntervalSince1970 < $1.timeIntervalSince1970})

print(convertedArray)
13

convertedArrayの余分な変数の回避

Swift 4およびSwift 3を使用

let testArray = ["25 Jun, 2016", "30 Jun, 2016", "28 Jun, 2016", "2 Jul, 2016"]

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd MM, yyyy"// yyyy-MM-dd"

var ready = convertedArray.sorted(by: { dateFormatter.date(from:$0).compare(dateFormatter.date(from:$1)) == .orderedDescending })

print(ready)
6
Prasen-ftech

historyArrayの配列を含む配列HistoryObjectがあります。各HistoryObjectには、「MM dd、yyyy」という形式の日付文字列が含まれます

編集:

(履歴オブジェクトを日付値で並べ替えます。日付stringsのオブジェクトを日付文字列で並べ替えることはお勧めできません。すべての比較のために日付文字列をCocoa Dateオブジェクトに変換する必要があるため、何度も何度も日付を日付オブジェクトに変換することになります。以下に概説するように、ソートする前に日付文字列をDateオブジェクトにバッチ変換する場合)

これを効率的に行うには、最初にすべてのオブジェクトのDate値を取得する必要があります。そのための1つの方法は、日付文字列から計算されるDate変数をHistoryObjectに追加することです。それをしたくない場合は、次のことができます。

  1. DateFormatterを使用して、履歴オブジェクトの配列をDateオブジェクトの配列にマップします。
  2. Zip()関数を使用して、履歴オブジェクトの配列と日付オブジェクトの配列を組み合わせてタプルの配列にします。
  3. タプルの配列をソートします。
  4. タプルの配列を履歴オブジェクトの配列にマップします。

そのためのコードは次のようになります。

バージョン1

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM dd, yyyy"

//I don't know what your HistoryObject looks like, so I'll fake it.
struct HistoryObject: CustomStringConvertible {
    let dateString: String
    let value: Int

    var description: String {
        return "date: \(dateString), value: \(value)"
    }
}

//Create an array of date strings.
let testArray = ["Jun 25, 2016", "Jun 30, 2016", "Jun 28, 2016", "Jul 2, 2016"]

//Use the array of date strings to create an array of type [HistoryObject]
let historyArray: [HistoryObject] = testArray.map {
    let value = Int(arc4random_uniform(1000))
    return HistoryObject(dateString: $0, value: value)
}

print("\n-----> Before sorting <-----")
historyArray.forEach { print($0) }

//Create an array of the `Dates` for each HistoryObject
let historyDates: [Date] = historyArray.map { dateFormatter.date(from: $0.dateString)!
}

//Combine the array of `Dates` and the array of `HistoryObjects` into an array of tuples
let historyTuples = Zip(historyArray, historyDates)

//Sort the array of tuples and then map back to an array of type [HistoryObject]
let sortedHistoryObjects = historyTuples.sorted { $0.1 > $1.1}
    .map {$0.0}

print("\n-----> After sorting <-----")
sortedHistoryObjects.forEach { print($0) }

HistoryObjectにlazy var dateを追加する場合、ソートコードはもっと簡単です:

バージョン2:

//I don't know what your HistoryObject looks like, so I'll fake it.
class HistoryObject: CustomStringConvertible {
    let dateString: String
    lazy var date: Date = { dateFormatter.date(from: self.dateString)! }()
    let value: Int

    var description: String {
        return "date: \(dateString), value: \(value)"
    }

    init(dateString: String, value: Int) {
        self.dateString = dateString
        self.value = value
    }
}

//Create an array of date strings.
let testArray = ["Jun 25, 2016", "Jun 30, 2016", "Jun 28, 2016", "Jul 2, 2016"]

//Use the array of date strings to create an array of type [HistoryObject]
let historyArray: [HistoryObject] = testArray.map {
    let value = Int(arc4random_uniform(1000))
    return HistoryObject(dateString: $0, value: value)
}

print("\n-----> Before sorting <-----")
historyArray.forEach { print($0) }

let sortedHistoryArray = historyArray.sorted { $0.date > $1.date }
print("\n-----> After sorting <-----")
sortedHistoryArray.forEach { print($0) }
2
Duncan C