Мне нужно несколько видов массива, но это не работает
Это ожидаемый результат. теперь этот массив перепутан
struct Variant {
var name: String
var count: Int
}
let array = [
Variant(name: "Ab", count: 12),
Variant(name: "Ac", count: 10),
Variant(name: "Ad", count: 8),
Variant(name: "Ae", count: 0)
Variant(name: "Bc", count: 55),
Variant(name: "Bd", count: 45)]
Я пытаюсь сделать это так, но он имеет приоритет по количеству и не заботится об имени
array = array.sorted(by: {
($0.count ?? 0, $1.name) > ($1.count ?? 0, $0.name)
})
Это ожидаемый результат. теперь это перепутано let array = [ Variant(name: "Ab", count: 12), Variant(name: "Ac", count: 10), Variant(name: "Ad", count: 8), Variant( имя: "Bc", количество: 55), Вариант (имя: "Bd", количество: 45)]
Я разместил ответ. Если вы хотите отдать предпочтение алфавитной сортировке, просто поменяйте порядок проверки условий, и вы получите желаемый результат.
Сравнение кортежей — хороший подход, но он должен быть ($0.name, $1.count) < ($1.name, $0.count) для вашей цели.
Чтобы отсортировать по нескольким критериям, просто включите условия, каскадирующие друг друга в зависимости от приоритета.
Обновлено: благодаря Мартину Р., указавшему на ошибку, вот исправленный код:
array.sorted(by: {
//First layer of filter. Sorts based on alphabetic order
if $0.name < $1.name {
return true
}
else if $0.name > $1.name {
return false
}
//Second layer. Sorts based on greater count
return $0.count > $1.count
})
Вход:
let array = [
Variant(name: "Bd", count: 55),
Variant(name: "Bc", count: 55),
Variant(name: "Ac", count: 12),
Variant(name: "Ab", count: 12),
Variant(name: "Ad", count: 8),
]
После сортировки:
Variant(name: "Ab", count: 12),
Variant(name: "Ac", count: 12),
Variant(name: "Ad", count: 8),
Variant(name: "Bc", count: 55),
Variant(name: "Bd", count: 55)
К сожалению, это не тот результат, которого я хочу. У меня должна быть группа по первой букве алфавита. Например, A, затем от наибольшего к наименьшему счету в A. И затем B, и так далее.
Вариант (имя: «Ab», количество: 55), Вариант (имя: «Ac», количество: 12), Вариант (имя: «Ad», количество: 8), Вариант (имя: «Bc», количество: 55 ), Вариант(название: "Бд", количество: 30)
Я отредактировал ответ. Думаю, это должно удовлетворить ваши требования. Как я уже сказал, вам просто нужно выполнить свои if проверки на основе приоритета сортировки.
Это неправильно. Прежде чем проверять второй слой, вы должны определить, определяет ли первый слой порядок. Поэтому вы должны проверить как $0.name < $1.name, так и $0.name > $1.name, прежде чем сравнивать подсчеты.
Этого можно добиться с помощью сравнения кортежей, как уже пробовали в вопросе, только это должно быть ($0.name, $1.count) < ($1.name, $0.count)
@MartinR Кроме того, ОП хочет, чтобы сортировка производилась по порядку «возрастающее имя» и «число по убыванию». Вот почему я предложил текущий подход
Сравнение кортежей — хороший подход к сортировке элементов по нескольким критериям, но вы неправильно определили порядок элементов кортежа.
Кортежи сравниваются в «лексикографическом порядке», начиная с первого (самого левого) элемента. Чтобы сначала отсортировать по имени, $0.name соотв. $1.name должен быть первым элементом кортежа.
Поэтому для упорядочения сначала по имени (по возрастанию), а затем по количеству (по убыванию) функция сортировки должна быть
array.sorted(by: {
($0.name, $1.count) < ($1.name, $0.count)
})
Показать ожидаемый результат