Array / Stack contains function

1k views Asked by At

I would like to give my STACK struct the function contains(element: Element) that returns a bool as to whether var contents contains the element provided.

struct Stack<T>: SequenceType, Equatable, Printable, DebugPrintable {
     typealias Element = T
     private var contents: [Element]
     var top: Int

     init(arrayLiteral elements: T...) {
          self.init(elements) }

     // easier initialization
     init<S: SequenceType where S.Generator.Element == Element>(_ sequence: S) {
          self.contents = [Element]()
          Swift.map(sequence) {self.contents[$0] = true }
     }

     // returns TRUE if the Stack contains <T> 'element'
     func contains(element: Element) -> Bool {
         return contents.filter(element != nil) ?? false
     }

I would like to be able to define a new STACK and search its contents like so:

 var newStack: Stack = [5, 23, 45, 100]
 newStack.contains(45)                      // returns TRUE

Currently the compiler gives an error of:

"Cannot invoke '??' with an argument list of type '(Array, BooleanLiteralConvertible)' "

1

There are 1 answers

0
Martin R On BEST ANSWER

First of all, the generic element type T must conform to Equatable so that you can compare the given element with the array elements using ==:

struct Stack<T : Equatable> : YourProtocols... {

The filter methods takes a closure which tests each array element:

let filtered = contents.filter({ $0 == element})

and returns a new array containing only the elements for which the test (the "predicate") yields true. But you don't need a new array, you want to test only for membership, and that can be done with the Swift contains() function:

func contains(element: Element) -> Bool {
    return Swift.contains(contents, element)
}

Btw, your init method does not compile. It seems to be copied from a different collection type where the elements are stored in a dictionary. Here you can simply use that an array can be initialized with a sequence:

init<S: SequenceType where S.Generator.Element == Element>(_ sequence: S) {
    self.contents = Array(sequence)
}