I have one function which is having some logic which have 2 foreach loop but i want to make code compact so I am trying to use compactmap
func getData() -> [String] {
var ids = [String]()
self.item?.connections?.forEach { connection in
connection.validLine?.forEach { line in
if let _ = line.connection?.links[LinkKey.dataGroups],
let dataGroups = line.dataGroupsCache, dataGroups.isContinue {
ids = checkinGroups.connections?.compactMap { $0.id } ?? []
}
}
}
return ids
}
so instead of 2 foreach i am trying to make in one by using self.item?.connections?.compactMap({ $0.validline })
but I am getting error saying "Type of expression is ambiguous without more context"
CodePudding user response:
I don't see how you can do it without to forEach
or compactMap
. Here is a possible solution:
func getData() -> [String] {
return item?.connections?.compactMap { connection in
connection.validLine?.compactMap { line in
guard let _ = line.connection?.links[LinkKey.dataGroups], line.dataGroupsCache?.isContinue == true else { return nil }
return checkinGroups.connections?.compactMap(\.id)
}
}
}
CodePudding user response:
Here's a translation of your post into something that is compilable and a direct translation into a version that doesn't use forEach.
I changed connectionIds
to ids
in your example because otherwise, you might as well just return []
.
class Example {
func getData() -> [String] {
var ids = [String]()
self.item?.connections?.forEach { connection in
connection.validLine?.forEach { line in
if let _ = line.connection?.links[LinkKey.dataGroups],
let dataGroups = line.dataGroupsCache, dataGroups.isContinue {
ids = checkinGroups.connections?.compactMap { $0.id } ?? []
}
}
}
return ids
}
func getDataʹ() -> [String] {
guard let connections = item?.connections else { return [] }
let numberOfProperLines = connections.flatMap { $0.validLine ?? [] }
.filter { line in
if let _ = line.connection?.links[LinkKey.dataGroups],
let dataGroups = line.dataGroupsCache, dataGroups.isContinue {
return true
} else {
return false
}
}
.count
return (0..<numberOfProperLines).flatMap { _ in checkinGroups.connections?.compactMap(\.id) ?? [] }
}
var checkinGroups: CheckInGroups!
var item: Item!
}
enum LinkKey: Int {
case dataGroups
}
struct Item {
let connections: [Connection]?
}
struct Connection {
let id: String?
let validLine: [Line]?
let links: [LinkKey: Void]
}
struct Line {
let dataGroupsCache: DataGroups?
let connection: Connection?
}
struct DataGroups {
let isContinue: Bool
}
struct CheckInGroups {
let connections: [Connection]?
}