skip to Main Content

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"

2

Answers


  1. 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)
            }
        }
    }
    
    Login or Signup to reply.
  2. 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]?
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search