我有一个包含结构数组的数据模型。我正在使用它来填充tableView。效果很好,但我需要帮助过滤数据。
我希望能够通过extremeSport枚举进行过滤(通过按下UI中的按钮。)在下面的示例中,有3个运动有8个技巧。最终,将有大约10项运动和150-200技巧(可能更多的技巧。)过滤在这里是有道理的。
问题是我不知道如何从Sections转到ExtremeModel,因此我可以通过extremeSport进行过滤。我得到的最接近的是按sectionName字母排序。
struct ExtremeModel {
let trick: String
let definition: String
let extremeSport: Sport
enum Sport {
case bmx
case skateboarding
case snowboarding
}
}
struct Sections {
let sectionName: String
let Objects: [ExtremeModel]
}
struct Data {
static func allTricks() -> [Sections] {
return [
Sections(sectionName: "A", Objects: [
ExtremeModel(trick: "Acid Drop", definition: "Lorem ipsum", extremeSport: .skateboarding),
ExtremeModel(trick: "Axel Stall", definition: "Lorem ipsum", extremeSport: .skateboarding)
]),
Sections(sectionName: "B", Objects: [
ExtremeModel(trick: "Back Flip", definition: "Lorem ipsum", extremeSport: .snowboarding),
ExtremeModel(trick: "Bar Spin", definition: "Lorem ipsum", extremeSport: .bmx),
ExtremeModel(trick: "Bunny Hop", definition: "Lorem ipsum", extremeSport: .bmx)
]),
Sections(sectionName: "S", Objects: [
ExtremeModel(trick: "Shifty", definition: "Lorem ipsum", extremeSport: .snowboarding),
ExtremeModel(trick: "Shuvit", definition: "Lorem ipsum", extremeSport: .skateboarding),
ExtremeModel(trick: "Stalefish", definition: "Lorem ipsum", extremeSport: .snowboarding)
]),
]
}
}
用法。这是我在排序时遇到麻烦的地方。
let allTerms = Data.allTricks()
// Here, I am filtering by Section Name. I want to filter by extremeSport, so I can update the view based on sports.
let filteredSports = allTerms.filter { (sport:Sections) -> Bool in
return sport.sectionName == "A"
}
如何通过extremeSport枚举过滤allTricks()数据?
答案 0 :(得分:2)
我会稍微修改你的模型。我建议您使用Dictionary
而不是Array
,这样您就可以更自然地找到您感兴趣的技巧。
enum ExtremeSport {
case bmx
case skateboarding
case snowboarding
}
struct ExtremeSportTrick {
let name: String
let definition: String
let extremeSport: ExtremeSport
}
struct SportData {
static let allTricks = [
ExtremeSportTrick(name: "Acid Drop", definition: "Lorem ipsum", extremeSport: .skateboarding),
ExtremeSportTrick(name: "Axel Stall", definition: "Lorem ipsum", extremeSport: .skateboarding),
ExtremeSportTrick(name: "Back Flip", definition: "Lorem ipsum", extremeSport: .snowboarding),
ExtremeSportTrick(name: "Bar Spin", definition: "Lorem ipsum", extremeSport: .bmx),
ExtremeSportTrick(name: "Bunny Hop", definition: "Lorem ipsum", extremeSport: .bmx),
ExtremeSportTrick(name: "Shifty", definition: "Lorem ipsum", extremeSport: .snowboarding),
ExtremeSportTrick(name: "Shuvit", definition: "Lorem ipsum", extremeSport: .skateboarding),
ExtremeSportTrick(name: "Stalefish", definition: "Lorem ipsum", extremeSport: .snowboarding)
]
static func allTricksByFirstLetter() -> [String: [ExtremeSportTrick]] {
return Dictionary(grouping: allTricks, by: { String($0.name.first!) })
}
static func allTricksBySport() -> [ExtremeSport: [ExtremeSportTrick]] {
return Dictionary(grouping: allTricks, by: { $0.extremeSport })
}
}
使用示例:
extension Dictionary {
func prettyString<T>() -> String where Dictionary.Value == [T] {
return Array(self)
.map{ key, values in """
\(key): [
\(values.map{ "\($0)" }.joined(separator: ",\n\t"))
]
""" }
.joined(separator: ",\n")
}
}
let allTricksBySport = SportData.allTricksBySport()
let allTricksByFirstLetter = SportData.allTricksByFirstLetter()
let allBMXTricks = allTricksBySport[.bmx]
let allATricks = SportData.allTricksByFirstLetter()["A"]
print("=== All tricks by sport:")
print(allTricksBySport.prettyString())
print("\n\n\n=== All tricks by first letter:")
print(allTricksByFirstLetter.prettyString())
print("\n\n\n=== All bmx tricks:")
print(allBMXTricks!.map{ "\($0)"}.joined(separator: ",\n"))
print("\n\n\n=== All tricks whose name starts with \"A\":")
print(allATricks!.map{ "\($0)"}.joined(separator: ",\n"))
结果:
=== All tricks by sport:
snowboarding: [
ExtremeSportTrick(name: "Back Flip", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.snowboarding),
ExtremeSportTrick(name: "Shifty", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.snowboarding),
ExtremeSportTrick(name: "Stalefish", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.snowboarding)
],
bmx: [
ExtremeSportTrick(name: "Bar Spin", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.bmx),
ExtremeSportTrick(name: "Bunny Hop", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.bmx)
],
skateboarding: [
ExtremeSportTrick(name: "Acid Drop", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding),
ExtremeSportTrick(name: "Axel Stall", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding),
ExtremeSportTrick(name: "Shuvit", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding)
]
=== All tricks by first letter:
B: [
ExtremeSportTrick(name: "Back Flip", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.snowboarding),
ExtremeSportTrick(name: "Bar Spin", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.bmx),
ExtremeSportTrick(name: "Bunny Hop", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.bmx)
],
A: [
ExtremeSportTrick(name: "Acid Drop", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding),
ExtremeSportTrick(name: "Axel Stall", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding)
],
S: [
ExtremeSportTrick(name: "Shifty", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.snowboarding),
ExtremeSportTrick(name: "Shuvit", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding),
ExtremeSportTrick(name: "Stalefish", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.snowboarding)
]
=== All bmx tricks:
ExtremeSportTrick(name: "Bar Spin", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.bmx),
ExtremeSportTrick(name: "Bunny Hop", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.bmx)
=== All tricks whose name starts with "A":
ExtremeSportTrick(name: "Acid Drop", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding),
ExtremeSportTrick(name: "Axel Stall", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding)
根据您对可变性的需求,这些数组的大小/数量等等,您可能希望使用lazy var
来实现allTricksByFirstLetter
和allTricksBySport
。
答案 1 :(得分:1)
前面有几个人指出:
我认为这是你正在尝试做的事情:
struct ExtremeModel {
var trick: String!
var definition: String!
var extremeSport: Sport!
enum Sport {
case bmx
case skateboarding
case snowboarding
}
}
// Struct names should be singular!
struct Section {
var sectionName: String!
var Objects: [ExtremeModel]!
}
// Renamed to avoid collision with Foundation's Data class
struct MyData {
static func allTricks() -> [Section] {
return [
Section(sectionName: "A", Objects: [
ExtremeModel(trick: "Acid Drop", definition: "Lorem ipsum", extremeSport: .skateboarding),
ExtremeModel(trick: "Axel Stall", definition: "Lorem ipsum", extremeSport: .skateboarding)
]),
Section(sectionName: "B", Objects: [
ExtremeModel(trick: "Back Flip", definition: "Lorem ipsum", extremeSport: .snowboarding),
ExtremeModel(trick: "Bar Spin", definition: "Lorem ipsum", extremeSport: .bmx),
ExtremeModel(trick: "Bunny Hop", definition: "Lorem ipsum", extremeSport: .bmx)
]),
Section(sectionName: "S", Objects: [
ExtremeModel(trick: "Shifty", definition: "Lorem ipsum", extremeSport: .snowboarding),
ExtremeModel(trick: "Shuvit", definition: "Lorem ipsum", extremeSport: .skateboarding),
ExtremeModel(trick: "Stalefish", definition: "Lorem ipsum", extremeSport: .snowboarding)
]),
]
}
}
let allTricks = MyData.allTricks()
let filteredSports = allTricks.filter { (section) -> Bool in
return section.Objects.contains(where: { (extremeModel) -> Bool in
return extremeModel.extremeSport == .skateboarding
})
}
print(filteredSports.count)