Search code examples
arraysswiftperformanceprocessing-efficiency

Efficient Swift Array Comparison


struct Area {
var name: String
var isSelected: Bool
}

I have two lists:

  • List One: It has the full list of Areas.
  • List Two: It has a subset of Areas from List One the user has selected (but selected state is not set)

What I want to do is to create a new list of Areas that has items from both lists but if an element from List One is in List Two I want to update the isSelected property to true.

I wrote the current method but its flawed and inefficient:

private func didGetCurrentUserSession(_ usersAreas: [Area]?, allAreas: [Area]){
        guard let usersAreas = usersAreas else {return}
        var newAreasList = [Area]()
        for area in allAreas {
            for userArea in usersAreas {
                if userArea.name == area.name {
                    newAreasList.append(Area(name: area.name, isSelected: true))
                    break
                }
            }
            newAreasList.append(Area(name: area.name, isSelected: false))
        }

        _loadingAreas.onNext(false)
        _areas.onNext(newAreasList)
    }

Any help with this would be highly appreciated. Would prefer to accomplish this by using very Swifty approach.


Solution

  • Let's get names of user areas:

    let userAreaNames = Set((usersAreas ?? []).map { $0.name })
    

    map the other areas

    let newAreas = allAreas.map { area in
       return Area(
           name: area.name,
           isSelected: userAreaNames.contains(area.name)
       )
    }