Re: I can't figure out how to use NSIndexSet
Re: I can't figure out how to use NSIndexSet
- Subject: Re: I can't figure out how to use NSIndexSet
- From: Bill Cheeseman <email@hidden>
- Date: Thu, 20 Nov 2003 18:37:40 -0500
on 2003-11-20 9:02 AM, John Clayton at email@hidden wrote:
>
That sums it up pretty much. Once I have it, how the heck can I
>
iterate through it? If I try this:
>
>
int *buf;
>
NSRange myRange
>
int indCount = [myIndexSet getIndexes:buf maxCount:200
>
inIndexRange:&myRange];
The indexSet that gets loaded into buf should be thought of as an array of
indexes. That is, buf is an array, and the values contained in its
successive elements are indexes into your table's datasource. The indexes
contained in the successive elements of the array may be noncontiguous,
which I assume is why it is called an index "set."
Therefore, you iterate through the successive elements of the indexSet, buf,
sequentially, as usual, using idx++ in a for loop with idx equal to 0, 1, 2,
3, etc. What you find in each of these sequential array elements is an index
into the table's datasource. This may represent a sparse array, so to speak.
For example, if your table supports discontiguous multiple selection, the
values you find in the sequential array elements might be 2, 4, 7, 19, etc.,
depending on which rows the user selected. It is these index values that you
use to index into your table's datasource.
For example, using the examples above, [myDatasource objectAtIndex:buf[0]]
gets the object displayed in row 2 because the value in buf[0] is 2;
[myDatasource objectAtIndex:buf[3]] gets the object displayed in row 19
because the value in buf[3] is 19; and so on.
So here's simple code to iterate through an indexSet representing selected
rows in a table that support multiple selection:
NSIndexSet *indexSet = [table selectedRowIndexes];
unsigned indexBuffer[[indexSet count]];
unsigned limit = [indexSet getIndexes:indexBuffer maxCount:[indexSet count]
inIndexRange:NULL];
unsigned idx;
for (idx = 0; idx < limit; idx++) {
[myClass seeObject:[myDatasource objectAtIndex:indexBuffer[idx]]];
}
This code creates an indexBuffer large enough to hold all the indexes, in
order to avoid having to deal with the inIndexRange: parameter. In other
words, 'limit' should come out equal to [indexSet count]. It is suitable for
a small datasource.
I should caution that this code is untested in this form. But it is only a
minor modification of code that is working in an application, so it should
be correct.
If your datasource has lots of elements (hundreds? thousands?), you'll want
to use the inIndexRange: parameter. This is left as an exercise because I
haven't tried it yet. My understanding of the documentation is that you
would set the indexBuffer variable to an arbitrary size that is smaller than
the size of the entire indexSet, or make it a pointer and don't specify a
size. Then call getIndexes:maxCount:inIndexRange: in an outer loop, passing
in a smallish range so the indexBuffer variable wouldn't be very big, then
iterate in an inner loop through that indexBuffer. When indexBuffer is
exhausted, crank the outer loop up a notch with another call to
getIndexes:maxCount:inIndexRange:, then iterate through indexBuffer in the
inner loop again. And so on. According to the documentation, the
inIndexRange: parameter gets adjusted automatically to handle each
successive chunk of data.
Once you find what you're looking for, you can exit the inner and outer
loops and move on.
Somebody correct me if I'm wrong.
--
Bill Cheeseman - email@hidden
Quechee Software, Quechee, Vermont, USA
http://www.quecheesoftware.com
The AppleScript Sourcebook -
http://www.AppleScriptSourcebook.com
Vermont Recipes -
http://www.stepwise.com/Articles/VermontRecipes
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.