Как создать 2D-массив из 1D-массива, используя карту и фильтр? - PullRequest
0 голосов
/ 08 октября 2018

Сегодня у меня есть желаемый вывод с использованием цикла, но как я могу заменить этот цикл на однострочное выражение, используя карту и фильтр?

Я начинаю с массива стран.Из этого я генерирую второй массив с начальными буквами, используя карту.Теперь я хотел бы построить 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 ]

0 голосов
/ 08 октября 2018

Вы можете использовать метод 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"]]\n"
0 голосов
/ 08 октября 2018

Вы можете map initial, установленный filtering countries strings 'первая буква строки как:

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]]), таких как:

[["Албания", "Алжир", "Ангола"], ["Багамские острова", "Бахрейн"], ["Канада"]]

0 голосов
/ 08 октября 2018

Вы можете достичь этого с помощью group> sort> 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])
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...