-2

I am using contains function in a function which array is a string array, like this:

func addArrayCheck(array: Array<String>, value: String) {
    if (array.contains(value)) {
        print("Element exists!")
    }
    else {
        print("Element does not exists!")
    }
}

Then I tried to make an extension, but Xcode complain about this:

Missing argument label 'where:' in call

extension Array {
    func addArrayCheck(value: Self.Element) {
        if self.contains(value) {
            print("Element exists!")
        }
        else {
            print("Element does not exists!")
        }
    }
}

Why I cannot use contains like I used in function in generic form? and how can I solve the issue?

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
ios coder
  • 1
  • 4
  • 31
  • 91
  • Are you planning to implement `addArrayCheck` to add elements, only if they're already not present in the array? – Alexander Aug 02 '22 at 15:28
  • Yes, that is correct, I do not want have same value in array, do you mean there is better way? @Alexander – ios coder Aug 02 '22 at 20:35
  • 1
    Yeah, you should probably avoid that, because `contains(_:)` has linear (`O(array.count)`) time complexity. If you're sure your array won't get long, it's fine, but I'd generally suggest just using a [`Set`](https://developer.apple.com/documentation/swift/set), or an [`OrderedSet`](https://github.com/apple/swift-collections/blob/main/Documentation/OrderedSet.md) if you need to preserve element order. – Alexander Aug 02 '22 at 21:00
  • I never saw OrderedCollections or OrderedSet before! Is it basically a set that we make an order at end? when we done with adding elements? @Alexander – ios coder Aug 02 '22 at 21:04
  • 2
    @ioscoder Check this related post [How to implement a Mutable Ordered Set generic type formerly known as NSMutableOrderedSet in native Swift?](https://stackoverflow.com/q/59887561/2303865) – Leo Dabus Aug 02 '22 at 21:28
  • @LeoDabus I love your step by step approach and breakdown. Even though I think this particular hand-rolled implementation like that is now obsolete because of swift-algorithms, this will be a great reference source for people interested in rolling their own collections and benefiting from the various algorithms built into the standard library. – Alexander Aug 02 '22 at 21:38
  • @ioscoder Yep. That markdown page explains it pretty well. – Alexander Aug 02 '22 at 21:40
  • @Alexander Thanks. Yes, I have already seen those swift algorithms. Many good collections implementations there. My intent was let OP understand which protocols are needed to implement something like append if not exist because when extending Sequence there is no append method available. – Leo Dabus Aug 02 '22 at 21:41

1 Answers1

4

That contains overload only works when your elements are Equatable.

extension Sequence where Element: Equatable {
  func addCheck(value: Element) {
    print(
      contains(value)
        ? "Element exists!"
        : "Element does not exist!"
    )
  }
}
  • I see you updated my approach with using Sequence, thanks, but Dictionary is not a Sequence?! your code works on array and set, but not in Dictionary, I think Dictionary is a Sequence, right? – ios coder Aug 02 '22 at 20:34
  • 1
    It's an unordered sequence of key-value pairs, yes. Those cannot be `Equatable` because they are tuples. –  Aug 02 '22 at 21:13