Как отсортировать строковый массив в swift по числовым и буквенным значениям? - PullRequest
0 голосов
/ 29 апреля 2020

Я пытаюсь отсортировать массив, который указан в следующем виде:

let array = ["02:00 AM", "01:00 AM", "01:00 PM", "01:01 AM", "01:01 PM", "03:00 AM"]

Я могу добавлять / обновлять свои пользовательские значения по умолчанию для напоминаний, однако я хочу, чтобы он сортировался не только по времени, но по значению AM / PM. таким образом массив выглядит так:

["01:00 AM", "01:01 AM", "02:00 AM", "03:00 AM", "01:00 PM","01:01 PM"]

Как я могу это сделать? Использование .sort() в массиве не работает, так как это будет просто сортировать по времени, но я специально хочу строки AM перед строками PM. У меня есть массив в виде строки, так как я думал, что это будет проще, но я вижу, что это может быть не лучшим способом.

Ответы [ 4 ]

0 голосов
/ 30 апреля 2020
let morningTimes = arrayOfTimes.filter{$0.contains("AM") && !$0.contains("12:")}.sorted()
let dayTimes = arrayOfTimes.filter{$0.contains("12:") && $0.contains("AM")}.sorted() + morningTimes
let nightTimes = arrayOfTimes.filter{$0.contains("PM") && !$0.contains("12:")}.sorted()
let allTimes = dayTimes + arrayOfTimes.filter{$0.contains("12:") && $0.contains("PM")}.sorted() + nightTimes
0 голосов
/ 29 апреля 2020

Фильтр до 12 & AM, затем сортировка. Фильтруйте по 12 & PM, затем сортируйте. Затем объедините 2 массива.

let array = ["12:00 AM", "12:02 PM", "02:00 AM", "01:00 AM", "01:00 PM", "01:01 AM", "01:01 PM", "03:00 AM"]

Мы должны учитывать, что № 12 повлияет на сортировку. Поэтому вам нужно отфильтровать все время с помощью 12, отсортировать их и поместить их впереди.

let amc = array.filter { $0.hasPrefix("12") }.filter { $0.hasSuffix("AM") }.sorted(by: <) + array.filter { !$0.hasPrefix("12") }.filter { $0.hasSuffix("AM") }.sorted(by: <)
let pmc = array.filter { $0.hasPrefix("12") }.filter { $0.hasSuffix("PM") }.sorted(by: <) + array.filter { !$0.hasPrefix("12") }.filter { $0.hasSuffix("PM") }.sorted(by: <)
let comb = amc + pmc
print(comb) // prints ["12:00 AM", "01:00 AM", "01:01 AM", "02:00 AM", "03:00 AM", "12:02 PM", "01:00 PM", "01:01 PM"]

С этим упражнением становится ясно, что использование Date - лучший подход.

0 голосов
/ 29 апреля 2020

Опираясь на ответ @nighttalker, вы можете получить его в одну строку, используя sorted(by: <).

Тогда код будет:

let array = ["02:00 AM", "01:00 AM", "01:00 PM", "01:01 AM", "01:01 PM", "03:00 AM"]
let sortedArray = array.filter { $0.contains("AM") }.sorted(by: <) + array.filter { $0.contains("PM") }.sorted(by: <)

, но, как сказал Арку, вам, вероятно, следует используйте тип Date и приведите его в соответствие с Comparable.

(я пока не могу комментировать, поэтому пришлось отправить его таким образом)

0 голосов
/ 29 апреля 2020

Вы можете передать sort блок и реализовать там логи сравнения c, например:

var array = ["02:00 AM", "01:12 AM", "01:00 PM", "01:01 AM", "01:01 PM", "03:00 AM", "12:15 AM", "12:30 AM", "12:01 PM", "12:30 PM" ]
array.sort { s1, s2 in
    let isAM1 = s1.contains("AM")
    let isAM2 = s2.contains("AM")
    return isAM1 && !isAM2 || ((isAM1 == isAM2) && s1 < s2)
}

Блок сравнения должен возвращать true тогда и только тогда, когда первый аргумент должен быть отсортировано до второго. Это реализовано здесь так, что либо первое - AM, а второе - PM, либо оба имеют одинаковый AM / PM, а первое имеет более раннее время.

PS. Вы можете рассмотреть возможность использования Date объектов вместо строки в первую очередь (вы всегда можете отформатировать их обратно в строки при необходимости).

Редактировать : Если в ваших строках используется соглашение, в котором "12:00 PM" - полдень, а "12 : 00:00 "полночь, такие времена будут неправильно отсортированы по вышеуказанному. Вы можете исправить это, протестировав s1.hasPrefix("12:") и инвертировав статус «is AM»:

if s1.hasPrefix("12:") {
    isAM1 = !isAM1
}
if s2.hasPrefix("12:") {
    isAM2 = !isAM2
}

Даже при таком подходе сортировка 12:59 AM последняя вместо прямой перед 01:00 AM - вы можете точно Настройте сравнение, если это проблема. Однако я думаю, что одна эта сложность является достаточной причиной для использования Date объектов (или ваших собственных Comparable временных держателей), а не строк. Предполагая, что вы не хотите переходить на 24-часовые часы. =)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...