У меня есть желаемый результат, используя цикл сегодня, но как я могу обменять этот цикл на однострочное выражение, используя карту и фильтр?
Я начинаю с множества стран. Из этого я генерирую второй массив с начальными буквами, используя карту. Теперь я хотел бы построить 2D-массив, содержащий все страны с одинаковой начальной буквой в отдельных массивах с использованием карты и фильтра, чтобы я мог избавиться от цикла, который я использую сегодня.
let countries = ["Albania", "Algeria", "Angola", "Bahamas", "Bahrain", "Canada"]
var initials = Set(countries.map { $0.prefix(1) }).sorted()
func countriesByInitial() -> [[String]] {
var result = [[String]]()
for initial in initials {
result.append(countries.filter { $0.prefix(1) == initial })
}
return result
}
Всего 3 ответа
Вы можете использовать метод Swift 4 reduce(into:)
если ваш массив уже отсортирован, иначе вам просто нужно отсортировать его перед группировкой:
let countries = ["Albania", "Algeria", "Angola", "Bahamas", "Bahrain", "Canada"]
let grouped: [[String]] = countries.reduce(into: []) {
if $0.last?.last?.prefix(1) == $1.prefix(1) {
$0[$0.index(before: $0.endIndex)].append($1)
} else {
$0.append([$1])
}
}
print(grouped) // [["Albania", "Algeria", "Angola"], ["Bahamas", "Bahrain"], ["Canada"]]
"
Вы можете достичь этого с помощью группы> sort> map map :
let countries = ["Algeria", "Albania", "Belarus", "Bahamas", "Canada"]
let groupedDict = Dictionary(grouping: countries, by: { $0.prefix(1) })
let sortedDict = groupedDict.sorted(by: { $0.key < $1.key })
let arr2D = sortedDict.map({ $0.value })
Вы можете написать его в одной строке:
let arr = (Dictionary(grouping: countries, by: { $0.prefix(1) })).sorted(by: { $0.key < $1.key }).map({ $0.value })
Вы можете также использовать сокращение по массиву:
// $ 0 будет иметь тип [[String]]
// $ 1 будет иметь тип String
let arr2D: [[String]] = countries.reduce(into: []) {
let checkChar = $1.first
if let idx = $0.index(where: {$0.first?.first == checkChar }) {
$0[idx].append($1)
} else {
$0.append([$1])
}
}
Вы можете сопоставить initial
набор, перенесив первую строку строк countries
следующим образом:
let countries = ["Albania", "Algeria", "Angola", "Bahamas", "Bahrain", "Canada"]
var initials = Set(countries.map { $0.prefix(1) }).sorted()
let array = initials.map { letter -> [String] in
return countries.filter { $0.prefix(1) == letter }
}
поэтому array
представляет собой массив массивов строк ( [[String]]
), так как:
[[«Албания», «Алжир», «Ангола»], [«Багамские Острова», «Бахрейн»], ["Канада"]]