Swift Array flatmap - PullRequest
       11

Swift Array flatmap

2 голосов
/ 15 марта 2019

Это упрощенное представление моей проблемы с использованием базы данных Realm.

struct Foo: CustomStringConvertible {
    var fooId: Int
    var fooName: String
    var bars: [String]

    var description: String {
        return "Foo: \(fooId) \(fooName) \(bars)"
    }
}

var ff = [Foo]()

var f1 = Foo(fooId: 1, fooName: "A", bars: ["A1", "A2", "A3"])
var f2 = Foo(fooId: 2, fooName: "B", bars: ["B1"])
var f3 = Foo(fooId: 3, fooName: "A", bars: ["A4", "A5"])
var f4 = Foo(fooId: 4, fooName: "B", bars: ["B2", "B3", "B4"])
var f5 = Foo(fooId: 5, fooName: "B", bars: ["B5"])
var f6 = Foo(fooId: 6, fooName: "A", bars: ["A6", "A7", "A8", "A9", "A10"])
var f7 = Foo(fooId: 7, fooName: "C", bars: ["C1", "C2", "C3"])

ff.append(contentsOf: [f1, f2, f3, f4, f5, f6, f7])

Я хочу использовать flatMap или compactMap для массива Foo на основе fooName, поэтому я могу создать карту fooName -> bars

A -> ["A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10"] B -> ["B1", "B2", "B3", "B4", "B5"] C -> ["C1", "C2", "C3"]

Ответы [ 2 ]

4 голосов
/ 15 марта 2019

Вы можете reduce(into:_:):

let results = ff.reduce(into: [String: [String]]()) { result, foo in
    result[foo.fooName, default: []].append(contentsOf: foo.bars)
}
2 голосов
/ 15 марта 2019

Это кажется довольно простым:

// group instances by fooName
let dict: Dictionary<String, [Foo]> = Dictionary(grouping: ff, by: { $0.fooName })
print(dict)
// flat map the [Foo] instances to [String] of their bars
let dict2: Dictionary<String, [String]> = dict.mapValues { foos in foos.flatMap { $0.bars } }
print(dict2)

или упрощенным:

let dict = Dictionary(grouping: ff, by: { $0.fooName })
    .mapValues { foos in foos.flatMap { $0.bars } }
print(dict)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...