Can somebody give a snippet of “append if not exis

2020-02-05 13:18发布

Because I use this routine a lot, can somebody create an extension method of Swift array which will detect whether if the data that is going to be appended already exists, then it's not appended? I know that it's only a matter of few code like this:

var arr = [Int]()
for element in inputArr {
    if !arr.contains(element) { arr.append(element); }
}

Becomes:

var arr = [Int]()
for element in inputArr { arr.appendUnique(element); }

Or:

var arr = [String]()
for element in inputArr {
    if !arr.contains(element) { arr.append(element); }
}

Becomes:

var arr = [String]()
for element in inputArr { arr.appendUnique(element); }

Same method for different element types. Frankly, from this simple code, I also want to learn on how to extend the Collection with variable types. It fascinates me how Array's methods can have different parameter types whenever the object was initialized with different parameter types. Array and Dictionary are two things that I still don't get how to extend them properly. Thanks.

3条回答
萌系小妹纸
2楼-- · 2020-02-05 13:40

In my case I was filtering results and appending on clicking search button with api response but appending uniquely slow down the process as it has to check every index for unique, I basically made my local array empty or simply arr.removeAll().

查看更多
来,给爷笑一个
3楼-- · 2020-02-05 13:47

You can extend RangeReplaceableCollection, constrain its elements to Equatable and declare your method as mutating. If you want to return Bool in case the appends succeeds you can also make the result discardable. Your extension should look like this:

extension RangeReplaceableCollection where Element: Equatable {
    @discardableResult
    mutating func appendIfNotContains(_ element: Element) -> (appended: Bool, memberAfterAppend: Element) {
        if let index = firstIndex(of: element) {
            return (false, self[index])
        } else {
            append(element)
            return (true, element)
        }
    }
}
查看更多
我想做一个坏孩纸
4楼-- · 2020-02-05 13:47

I needed to prepend a unique element (removing it first if it already exists).

extension RangeReplaceableCollection where Element: Equatable
{
    mutating func prependUnique(_ element: Element) {
        if let index = firstIndex(of: element) {
            remove(at: index)
        }
        insert(element, at: startIndex)
    }
}
查看更多
登录 后发表回答