Check if one Range is within another [closed]

喜夏-厌秋 提交于 2021-01-29 18:03:21

问题


let smallRange = 1..<2
let largeRange = 0..<10
largeRange ~= smallRange // False

Why does this compile at the first place!?
But if it compiles the answer should be True

The next code works:

smallRange.clamped(to: largeRange) == smallRange // True

Is there any simpler way to check?


回答1:


I don't think you will find a "simpler" or "shorter" way of writing this but you can define your own pattern matching operator to shorten your code:

extension Range {
    static func ~=(lhs: Self, rhs: Self) -> Bool {
        rhs.clamped(to: lhs) == rhs
    }
}

extension ClosedRange {
    static func ~=(lhs: Self, rhs: Self) -> Bool {
        rhs.clamped(to: lhs) == rhs
    }
}

let smallRange = 1..<2
let largeRange = 0..<10
smallRange ~= largeRange // false
largeRange ~= smallRange // true

Note: It compiles because there is a generic implementation used to check for equality like switching a string therefore it would only return true if both ranges were the same.

func ~= <T>(a: T, b: T) -> Bool where T : Equatable



回答2:


You seem to have a working formula. So why not just use it? Problem solved. If, however, you think your working formula is too long, hard to remember, whatever, then simply refactor it into an extension so you can shorten it:

extension Range {
    func embraces(_ other: Self) -> Bool {
        return other.clamped(to: self) == other
    }
}

Now you can say

largeRange.embraces(smallRange) // true

That's shorter. Simpler. Whatever.

That's (part of) what programming is. If you don't like the language, change it.




回答3:


You can compare the lowerBound and upperBound of the 2 ranges (or use the contains function to check that one range contains both bounds of the other range) to learn if one is a subset of the other.

extension Range {
    func contains(otherRange: Range) -> Bool {
        lowerBound <= otherRange.lowerBound && upperBound >= otherRange.upperBound
    }
}

let smallRange = 1..<2
let middleRange = 5..<8
let largeRange = 0..<10

smallRange.contains(otherRange: middleRange) // false
middleRange.contains(otherRange: smallRange) // false
largeRange.contains(otherRange: middleRange) // true

The other solution using contains:

extension Range {
    func contains(otherRange: Range) -> Bool {
        contains(otherRange.lowerBound) && contains(otherRange.upperBound)
    }
}



回答4:


Well, if one range is between another, it means that the edges are between each other So, in your example, it would be largeRange.first < smallRange.first && largeRange.last > smallRange.last



来源:https://stackoverflow.com/questions/64066681/check-if-one-range-is-within-another

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!