skip to Main Content

I have 7 arrays of Strings.

var redArray : [String] = ["2022-07-13", "2022-07-14","2022-07-15"]
var blueArray : [String] = ["2022-07-13", "2022-07-14","2022-07-16"]
...
And five more of the same format

I’m trying to create a method that will go through seven arrays and work like the following one (example below works for two arrays):

       if redArray.contains(someDate) && blueArray.contains(someDate)
        {
            return [UIColor.red, UIColor.blue]
        }
        else
        
        if redArray.contains(someDate)
        {
            return [UIColor.red]
        }
        else if blueArray.contains(someDate)
        {
            return [UIColor.blue]
        }

        return [UIColor.clear]

So it should find matches of dates in arrays and return an UIColor of arrays with this matches. In case there is no match – a single colour should be returned. It’s easy to do it for two arrays. But I don’t understand how can I loop through 7 of them 🙁

Of course, it can be done manually. But I guess there must be a smart way to implement the loop – though I’m not smart enough to figure it out how.

P.S. I don’t know, if it is important, but the function where this method will be used is the following:

func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance,eventDefaultColorsFor date: Date) -> [UIColor]?
    {
       ...
    }

2

Answers


  1. Try this:

    func loop(someDate: String, arrays: [([String], UIColor)]) -> [UIColor] {
        let containingArrays = arrays.filter({$0.0.contains(someDate)})
        return containingArrays.isEmpty ? [.clear]: containingArrays.map({$0.1})
    }
    

    Usage: loop(someDate: "some Date", arrays: [(["Test1"], .red), (["Test2"], .blue)])

    Login or Signup to reply.
  2. You could simply do that:

    var colors: [UIColor] = []
    
    if redArray.contains(someData) {
        colors.append(.red)
    }
    if blueArray.contains(someData) {
        colors.append(.blue)
    }
    if greenArray.contains(someData) {
        colors.append(.green)
    }
    
    return colors.isEmpty ? [.clear] : colors
    

    If you really want loops, starting with:

    let tuples: [(UIColor, [String])] = [(.red, redArray), (.blue, blueArray), (.green, greenArray)]
    var colors: [UIColor] = []
    

    Basic for loop:

    for aTuple in tuples {
        if aTuple.1.contains(someData) {
            colors.append(aTuple.0)
        }
    }
    

    Basic for loop with where:

    for aTuple in tuples where aTuple.1.contains(someData) {
        colors.append(aTuple.0)
    }
    

    With a forEach:

    tuples.forEach {
        if $0.1.contains(someData) {
            colors.append($0.0)
        }
    }
    

    If you prefer reduced(into:_:):

    let colors = tuples.reduce(into: [UIColor]()) { partialResult, current in
        guard current.1.contains(someData) else { return }
        partialResult.append(current.0)
    }
    

    And still return colors.isEmpty ? [.clear] : colors at the end.

    Edit: As suggested in comments, there is also the compactMap() solution. It can be seen as a map() + filter() in one loop.

    let colors = tuples.compactMap { aTuple in
        if aTuple.1.contains(someData) {
            return aTuple.0
        } else {
            return nil
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search