10

I've found the .contains(Element) method pretty essential in my minimal experience writing Swift code, and have quickly realized that Apple changed it...

func contains(check:[[[Int]]], forElement: [[Int]]) -> Bool {
    for element in check {
        if areEqual(element, forElement) {
            return true
        }
    }
    return false
}
func areEqual(_ a:[[Int]], _ b:[[Int]]) -> Bool {
    for i in 0..<a.count {
        if a[i] != b[i] {
            return false
        }
    }
    return true
}

I've been messing with some large arrays, so I fixed my problem with that clunky function.

What happened?

How do you use the new way?

The example there is well over my head.

enum HTTPResponse {
    case ok
    case error(Int)
}

let lastThreeResponses: [HTTPResponse] = [.ok, .ok, .error(404)]
let hadError = lastThreeResponses.contains { element in
    if case .error = element {
        return true
    } else {
        return false
    }
}
// 'hadError' == true
3
  • What are kind of values are in the array you're trying to call contains on? Can you show some code of how you're trying to use contains? Commented Jun 12, 2017 at 18:49
  • Actually contains(where: is available in Swift 3, too. Commented Jun 12, 2017 at 18:51
  • 1
    I'm not aware of any changes made to contains(_:) or contains(where:) in Swift 4 – could you expand on what you think has changed? [[Int]] is not Equatable because we don't have conditional conformances yet – so you should use contains(where:) with an overload of == for nested arrays, compare stackoverflow.com/q/33377761/2976878 for how to define that. Commented Jun 12, 2017 at 18:53

2 Answers 2

32

How about using this

let numbers = [1, 2, 3, 4]
let contains = numbers.contains(where: { $0 == 3 })
//contains == true

Or

let strings = ["A", "B", "C", "D"]
let contains = strings.contains(where: { $0 == "B" })
//contains == true

Even with other objects like NSColor

let colors: [NSColor] = [.red, .blue, .green]
contains = colors.contains(where: { $0 == .red })
//contains == true
Sign up to request clarification or add additional context in comments.

2 Comments

invalid solution.
@VinitIngale this works for me, would you care to elaborate?
3

That API just lets you pass a block where you can perform any checks you want. You can check whether the given element is equal to something, or whether its properties satisfy some constraints (such as in the example in the documentation). You should be able to perform a basic equality check like this:

func contains(check:[[[Int]]], forElement: [[Int]]) -> Bool {
    return check.contains { element in
        return areEqual(element, forElement)
    }
}

func areEqual(_ a:[[Int]], _ b:[[Int]]) -> Bool {
    for i in 0..<a.count {
        if a[i] != b[i] {
            return false
        }
    }
    return true
}

The contains block iterates over every element and returns either true or false. In the end, a single true for any element will return true for the whole function.

2 Comments

@Hamish fixed the closing brace. Forgot about the nested arrays portion, taking a look.
I modified the code to use the areEqualfunction in the question since as @Hamish pointed out, there is no built-in overload for nested arrays.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.