This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 9 - Pages: 1 - Last Post: 20 Jun 15, 15:39 Last Post By: JeffTucker
JeffTucker

Posts: 8,197
Registered: 31-Jan-2006
Mimicking fileiterator
Posted: 16 Jun 15, 15:10
 
  Click to reply to this thread Reply
To squeeze out a little efficiency, I've got a situation in which I want to replace some <ja:fileiterator> tags with BeanShell routines (my code is currently bouncing in and out of BeanShell in this situation, which is not ideal). If I want to iterate over all the objects in the current directory, that's no problem:
for(AlbumObject obj : currentFolder.getChildren()) {
	if(obj.isIncluded() && !obj.isHidden()) {
		do something;
	}
}
This mimics the behavior of <ja:fileiterator start=0>.

But the plain <ja:fileiterator> tag does something a bit different. It iterates over the objects on the current index page, which may be only a subset of the directory. Before I reinvent the wheel, does anyone have a nice chunk of code that properly restricts that "for" loop?
Dschuwi

Posts: 231
Registered: 12-Nov-2003
Re: Mimicking fileiterator
Posted: 17 Jun 15, 14:06   in response to: JeffTucker in response to: JeffTucker
 
  Click to reply to this thread Reply
Maybe this helps. CA2 does its own iteration like this:

// Starting index
int startIndex = (indexNum == void) ? 0 : (indexNum-1) * (rows*cols);
 
// Rows iteration
for (int i=0; i<currentRows; i++)
{
int index = startIndex + (i*cols);
 
  // Cols iteration 
  for (int j=0; j<cols; j++)
  {
    if (index+j < files.length)
    {
      doSomething();
    }
  }
 
}
JeffTucker

Posts: 8,197
Registered: 31-Jan-2006
Re: Mimicking fileiterator
Posted: 17 Jun 15, 14:20   in response to: Dschuwi in response to: Dschuwi
 
  Click to reply to this thread Reply
That's not unlike what I've ended up with. The tricky part of it turns out to be hidden and excluded objects. When you iterate through currentFolder.getChildren(), those objects are present, but the index page pagination, along with things like getTotalCount(), do not include the hidden and excluded objects.

So, I'm doing a variation on this (simplified because the skin does something a little more involved):
perPage = indexNum == void ? JAlbumUtilities.countCategories(currentFolder, false).getTotalCount() : cols * rows;
firstThisPage = indexNum == void ? 1 : 1 + (perPage * (indexNum - 1));
lastThisPage = firstThisPage + perPage - 1;
ctr = 0;
for(AlbumObject obj : currentFolder.getChildren()) {
	if(obj.isIncluded() && !obj.isHidden()) {
		if(++ctr > lastThisPage) break;
		if(ctr >= firstThisPage) {
			do something
		}
	}
}
When you're on, say, index5.html, I don't think there's any way to "jump into" the AlbumObjects - you have to march through from the beginning so that you're not counting the hidden or excluded objects.
davidekholm

Posts: 3,915
Registered: 18-Oct-2002
Re: Mimicking fileiterator
Posted: 19 Jun 15, 12:03   in response to: JeffTucker in response to: JeffTucker
 
  Click to reply to this thread Reply
One performance note. The isHidden() call is expensive to call on an image-by-image basis as it leads to the attempt to load a .info file for each image. As jAlbum currently only allows for hidden folders, you may adjust code
if (obj.isIncluded() && !obj.isHidden())
to
if (obj.isIncluded() && obj.isFolder() && !obj.isHidden())
then the isHidden() check is only performed on folders.
JeffTucker

Posts: 8,197
Registered: 31-Jan-2006
Re: Mimicking fileiterator
Posted: 19 Jun 15, 12:47   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
Good tip, but that's going to ignore images completely, isn't it? They'll fail the isFolder() test.

If I want to target things on the page, images and folders, I suppose this would be more efficient:
if(obj.isIncluded() && (!obj.isFolder() || !obj.isHidden()))
davidekholm

Posts: 3,915
Registered: 18-Oct-2002
Re: Mimicking fileiterator
Posted: 20 Jun 15, 12:38   in response to: JeffTucker in response to: JeffTucker
 
  Click to reply to this thread Reply
jGromit wrote:
Good tip, but that's going to ignore images completely, isn't it? They'll fail the isFolder() test.

Yes

If I want to target things on the page, images and folders, I suppose this would be more efficient:
if(obj.isIncluded() && (!obj.isFolder() || !obj.isHidden()))

Yes, that's correct and performant.
RobM

Posts: 3,948
Registered: 4-Aug-2006
Re: Mimicking fileiterator
Posted: 20 Jun 15, 13:52   in response to: davidekholm in response to: davidekholm
 
  Click to reply to this thread Reply
davidekholm wrote:
jGromit wrote:
If I want to target things on the page, images and folders, I suppose this would be more efficient:
if(obj.isIncluded() && (!obj.isFolder() || !obj.isHidden()))
Yes, that's correct and performant.
Obviously the actual code must be working, but for code copiers like me count the number of ')'! ;)
JeffTucker

Posts: 8,197
Registered: 31-Jan-2006
Re: Mimicking fileiterator
Posted: 20 Jun 15, 13:54   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
Count again. Your fingers will suffice. ;)
RobM

Posts: 3,948
Registered: 4-Aug-2006
Re: Mimicking fileiterator
Posted: 20 Jun 15, 15:33   in response to: JeffTucker in response to: JeffTucker
 
  Click to reply to this thread Reply
Obviously I am seeing double in the right eye! And no, I have not touched a drop of alcohol - yet ;)
I must start to wear my prescription corrective glasses, though I don't think it will help as I expanded the screen to make the text nice and big. It must be a bit like one of those sentences where you are asked to count the number of 'F' letters in a sentence, you know where the brain ignores 'if' and 'of' but recognises su'ff'ice.

I'm of for a lie down in a quiet room, where I can sit in quiet embarrassment!
JeffTucker

Posts: 8,197
Registered: 31-Jan-2006
Re: Mimicking fileiterator
Posted: 20 Jun 15, 15:39   in response to: RobM in response to: RobM
 
  Click to reply to this thread Reply
Exactly how many barrels of sherry do you keep in the basement?

In any event, unless there's some other magic trick that I'm missing, here's the final code to mimic a <ja:fileiterator>, with one more little revision to use a variable that's already available rather than calculating it again:
perPage = indexNum == void ? indexImageCount : cols * rows;
firstThisPage = indexNum == void ? 1 : 1 + (perPage * (indexNum - 1));
lastThisPage = firstThisPage + perPage - 1;
ctr = 0;
for(AlbumObject obj : currentFolder.getChildren()) {
	if(obj.isIncluded() && (!obj.isFolder() || !obj.isHidden())) {
		if(++ctr > lastThisPage) break;
		if(ctr >= firstThisPage) {
			do something
		}
	}
}
Legend
Forum admins
Helpful Answer
Correct Answer

Point your RSS reader here for a feed of the latest messages in all forums