【问题标题】:Do these two ranges intersect? If so, how do I know?这两个范围相交吗?如果是这样,我怎么知道?
【发布时间】:2014-06-27 18:22:47
【问题描述】:

来自苹果的documentation

返回值 描述 range1 和 range2——即一个包含两个索引的范围 范围。

讨论如果返回范围的长度字段为0,那么这两个 范围不相交,并且位置字段的值为 未定义。

好的,假设我有两个范围:

(lldb) p rangeOne
(NSRange) $3 = location=11, length=4
(lldb) p rangeTwo
(NSRange) $4 = location=14, length=0

我计算交点:

NSRange intersection = NSIntersectionRange(rangeOne, rangeTwo);

结果是:

(lldb) p intersection
(NSRange) $5 = location=14, length=0

我该怎么办?长度为零,所以位置未定义?但在这种情况下,结果是我所期望的;我可以相信吗?计算一个范围的长度为零的范围的交集是否无效?

【问题讨论】:

  • 在我看来,零长度的范围无论如何都是没有意义的,但是如果您在这种情况下想要“交集”并且不信任 NSIntersectionRange 那么为什么不自己编写代码。这是一个相当简单的算法,如果你想清楚的话。
  • 好吧,我正在处理文本,并且经常选择的范围为零,因为插入点只是在移动,我没有选择。我想知道插入点是否在特定范围内。由于他们决定将 NSRange 用于所有这些东西,我原以为会出现这种情况。我确实根据自己的需要编写了自己的代码,但我想了解我在这里不了解的内容。
  • rangeTwo 是否定义了索引?如果是这样,那么该索引显然在rangeOne 内,并且它们应该相交。还是length 为零的范围没有定义索引?
  • 对于插入,在我看来,您只想知道第二个点是否在第一个范围内。

标签: ios objective-c foundation nsrange


【解决方案1】:

你是对的。您必须使用文档。该值不可用。 API 中有什么漏洞!


作为一个快速的想法,类似于汤米的回答,这是一个具有更强承诺的版本

// Like NSIntersectionRange() except it returns location of NSNotFound and
// length of NSNotFound when the ranges do not intersect.
static inline NSRange MyIntersectionRange(NSRange range1, NSRange range2)
{
    if (range1.location == NSNotFound || range1.length == NSNotFound ||
        range2.location == NSNotFound || range2.length == NSNotFound)
        return NSMakeRange(NSNotFound, NSNotFound);

    NSUInteger begin1 = range1.location;
    NSUInteger end1 = range1.location + range1.length;
    NSUInteger begin2 = range2.location;
    NSUInteger end2 = range2.location + range2.length;

    if (end1 <= begin2 || end2 <= begin1)
        return NSMakeRange(NSNotFound, NSNotFound);

    NSUInteger begin = MAX(begin1, begin2);
    NSUInteger end = MIN(end1, end2);

    return NSMakeRange(begin, end - begin);
}

返回值为正确答案。您的范围从 14 的位置开始,长度为 0。长度为 0 并不意味着该范围无效。

这是一个使用长度为 0 的示例。

NSString *x = @"abcdefg";
NSString *y = @"123";
NSRange range = NSMakeRange(4, 0);
NSString *z = [x stringByReplacingCharactersInRange:range withString:y];
NSLog(@"%@", z);

结果

2014-06-27 14:29:53.610 TestApp[10501:303] abcd123efg

在本例中,长度为 0 表示该位置是一个插入点,不会删除任何现有字符串。

如果您需要不同的答案,请自行计算。

【讨论】:

  • 长度为零的范围是有效的,但交集函数的文档特别重载了长度为零的含义,表示位置无效。
  • @jeffamaphone 好的,我明白了。哇,这对苹果来说是糟糕的设计。您必须使用文档,长度为 0 表示结果不可靠。
  • @jeffamaphone 我更新了我的答案。我希望它有用。
【解决方案2】:

我不认为NSIntersectionRange 公开了这些信息,这是荒谬的,因为他们可以将location 设置为NSNotFound 或其他东西。所以你必须手动完成。我怀疑你需要博览会,但例如:

BOOL NSRangeIntersectsRange(NSRange range1, NSRange range2)
{
    if(range1.location > range2.location + range2.length) return NO;
    if(range2.location > range1.location + range1.length) return NO;
    return YES;
}

(可能使用比NS更合适的方法名称前缀)

【讨论】:

    【解决方案3】:

    如果返回范围的长度字段为0,则两个范围不相交,并且位置字段的值未定义。

    我将其解释为当 length 为 0 时,范围不相交。

    BOOL RangesIntersect(NSRange range1, NSRange range2) {
        return NSIntersectionRange(range1, range2).length != 0;
    }
    

    同意 Tommy 的观点——他们本可以将其设置为 NSNotFound——但他们却说结果是未定义的。此外,我同意零长度范围的位置是没有意义的。 rangeTwo 中的位置没有任何意义。 rangeTwo 也不能与任何东西相交。

    【讨论】:

      【解决方案4】:

      这不是错误..您的范围二的长度为 0,因此与不存在相同...因此,当您执行 NSRange 交集 = NSIntersectionRange(rangeOne, rangeTwo) 时,交集的长度当然为 0,因为您不能与长度为 0 的东西相交!!

      【讨论】:

        【解决方案5】:

        “我该怎么办?”

        NSIntersectionRange 正在按预期工作。如果不能满足你的需求,你可以自己写。

        “计算一个范围长度为零的范围的交集是否无效?”

        这不是无效的,但很明显:他们不这样做是因为他们不能。

        【讨论】:

          猜你喜欢
          • 2014-01-30
          • 1970-01-01
          • 2021-12-08
          • 1970-01-01
          • 1970-01-01
          • 2021-09-18
          • 2019-06-14
          • 1970-01-01
          • 2011-02-08
          相关资源
          最近更新 更多