Search code examples
arraysswiftsetrangehashable

How to get an array having unique ranges from the array with duplicated ranges?


I can get an array of unique numbers from the array having duplicated numbers

let arrayWithReapeats = [1, 2, 3, 7, 3]
let unique = Array(Set(arrayWithReapeats))

I need an array having unique ranges

Range<String.Index>

from the array having duplicated ranges for instance like this.

let arrayWithReapeatsIdexes = [1..<5, 3..<9, 9..<25, 3..<9]

I cannot use the same approach with Set since only String, Int, Double, and Bool are hashable by default. How to make ranges hashable to be able to use the approach above?


Solution

  • The only requirement for the hash value is

    x == y implies x.hashValue == y.hashValue

    which means that the "trivial" hash function

    extension Range : Hashable {
        public var hashValue: Int {
            return 0
        }
    }
    

    is valid and works:

    let arrayWithRepeatingIndexes = [1..<5, 3..<9, 9..<25, 3..<9]
    let arrayWithUniqueIndexes = Array(Set(arrayWithRepeatingIndexes))
    
    print(arrayWithUniqueIndexes)
    // [Range(1..<5), Range(3..<9), Range(9..<25)]
    

    You can also use the fact that the distance from start to end index is a integer type (and thus has a hash value):

    public var hashValue: Int {
        return startIndex.distanceTo(endIndex).hashValue
    }
    

    or compute the hash value from the description string (such as "3..<9"):

    public var hashValue: Int {
        return description.hashValue
    }
    

    You'll have to figure out which one is the most effective for your purpose.