使用 NSRange 循环

发布于 2024-12-18 17:02:15 字数 223 浏览 1 评论 0 原文

我正在尝试使用 NSRange 来保存一系列年份,例如

NSRange years = NSMakeRange(2011, 5);

我知道 NSRange 主要用于过滤,但是我想循环该范围内的元素。如果不将 NSRange 转换为 NSArray ,这可能吗?

I'm trying to use NSRange to hold a range of years, such as

NSRange years = NSMakeRange(2011, 5);

I know NSRange is used mostly for filtering, however I want to loop over the elements in the range. Is that possible without converting the NSRange into a NSArray?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

但可醉心 2024-12-25 17:02:15

听起来好像您期望 NSRange 就像 Python range 对象一样。它不是; NSRange 只是一个结构体

typedef struct _NSRange {
       NSUInteger location;
       NSUInteger length;
} NSRange;

而不是对象。一旦创建了一个,您就可以在普通的旧 for 循环中使用其成员:(

NSUInteger year;
for(year = years.location; year < NSMaxRange(years); year++ ){
    // Do your thing.
}

仍然假设您正在考虑 Python。)ObjC 中有一种名为 快速枚举用于迭代NSArray 的内容与 Python for 循环非常相似,但由于文字和原始数字不能放入 NSArray ,您不能直接从 NSRange 转到 Cocoa 数组。

不过,类别可以使这变得更容易:

@implementation NSArray (WSSRangeArray)

+ (id)WSSArrayWithNumbersInRange:(NSRange)range
{
    NSMutableArray * arr = [NSMutableArray array];
    NSUInteger i;
    for( i = range.location; i < NSMaxRange(range); i++ ){
        [arr addObject:[NSNumber numberWithUnsignedInteger:i]];
    }

    return arr;
}

然后您可以创建一个数组并使用快速枚举:

NSArray * years = [NSArray WSSArrayWithNumbersInRange:NSMakeRange(2011, 5)];
for( NSNumber * yearNum in years ){
    NSUInteger year = [yearNum unsignedIntegerValue];
    // and so on...
}

It kind of sounds like you're expecting NSRange to be like a Python range object. It's not; NSRange is simply a struct

typedef struct _NSRange {
       NSUInteger location;
       NSUInteger length;
} NSRange;

not an object. Once you've created one, you can use its members in a plain old for loop:

NSUInteger year;
for(year = years.location; year < NSMaxRange(years); year++ ){
    // Do your thing.
}

(Still working on the assumption that you're thinking about Python.) There's syntax in ObjC called fast enumeration for iterating over the contents of an NSArray that is pleasantly similar to a Python for loop, but since literal and primitive numbers can't be put into an NSArray, you can't go directly from an NSRange to a Cocoa array.

A category could make that easier, though:

@implementation NSArray (WSSRangeArray)

+ (id)WSSArrayWithNumbersInRange:(NSRange)range
{
    NSMutableArray * arr = [NSMutableArray array];
    NSUInteger i;
    for( i = range.location; i < NSMaxRange(range); i++ ){
        [arr addObject:[NSNumber numberWithUnsignedInteger:i]];
    }

    return arr;
}

Then you can create an array and use fast enumeration:

NSArray * years = [NSArray WSSArrayWithNumbersInRange:NSMakeRange(2011, 5)];
for( NSNumber * yearNum in years ){
    NSUInteger year = [yearNum unsignedIntegerValue];
    // and so on...
}
梦明 2024-12-25 17:02:15

请记住,NSRange 是一个包含两个整数的结构,表示范围的开始和长度。您可以使用 for 循环轻松循环所有包含的整数。

NSRange years = NSMakeRange(2011, 5);
NSUInteger year;
for(year = years.location; year < years.location + years.length; ++year) {
    // Use the year variable here
}

Remember that a NSRange is a structure holding two integers, representing the start and length of the range. You can easily loop over all of the contained integers using a for loop.

NSRange years = NSMakeRange(2011, 5);
NSUInteger year;
for(year = years.location; year < years.location + years.length; ++year) {
    // Use the year variable here
}
心清如水 2024-12-25 17:02:15

这是一个有点老的问题,但是使用 NSArray 的替代方法是创建一个具有所需范围的 NSIndexSet (使用 indexWithIndexesInRange: > 或 initWithIndexesInRange:),然后使用块枚举,如 https://stackoverflow.com/a/4209289/138772。 (似乎相关,因为我自己刚刚检查过这一点。)

This is a bit of an old question, but an alternative to using an NSArray would be to create an NSIndexSet with the desired range (using indexWithIndexesInRange: or initWithIndexesInRange:) and then using block enumeration as in https://stackoverflow.com/a/4209289/138772. (Seemed relevant as I was just checking on this myself.)

雄赳赳气昂昂 2024-12-25 17:02:15

我的替代解决方案是定义一个宏,以使速记更快。

#define NSRangeEnumerate(i, range)    for(i = range.location; i < NSMaxRange(range); ++i)

要称呼它,您可以这样做:

NSArray *array = @[]; // must contain at least the following range...
NSRange range = NSMakeRange(2011, 5);
NSUInteger i;
NSRangeEnumerate(i, range) {
    id item = array[i];
    // do your thing
}

就我个人而言,我仍在尝试弄清楚如何编写宏,以便我可以这样称呼它:

NSRangeEnumerate(NSUInteger i, range) {

}

尚不支持...希望可以帮助或使您更快地输入程序

My alternate solution for this, was to define a macro just to make shorthand quicker.

#define NSRangeEnumerate(i, range)    for(i = range.location; i < NSMaxRange(range); ++i)

To call it you do:

NSArray *array = @[]; // must contain at least the following range...
NSRange range = NSMakeRange(2011, 5);
NSUInteger i;
NSRangeEnumerate(i, range) {
    id item = array[i];
    // do your thing
}

personally I am still trying to figure out how I can write the macro so I can just call it like:

NSRangeEnumerate(NSUInteger i, range) {

}

which is not supported just yet... hope that helps or makes typing your program quicker

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文