I seem to remember discussing this before publically, but can't find any reference to it, so I'm blogging now in the hope somebody finds it useful (or in case I need it again at some point -- as the fact evaluate returns a Double has caught me out more than once now).

Update

Jesse Gallagher made a suggestion and did a little investigation to validate that the following method is much more efficient (see comments for more details):

Obviously you'd define and set the ViewNavigator once at the beginning of the code. You could always simply pass the name of the view as a String to the function and let it get view each time, but that would be plain crazy!

I bow down to your superior wisdom! Now you've explained it it makes sense. Without the explanation I'd expected the more obvious result of it returning either a 1 or 0 | "1" or "0" | "True" or "False" .

It's hard to say what my exact use case was without breaking confidentiality agreements, but this is the 2nd time I've used the same approach. It is useful. Enough for me to think it worthy or posting here.

Based on the principle that the selection formula for some views is representative of the business logic for a database, it shouldn't be too hard to think of a case where you need to check whether a document is in a view or not.

Oh, I like this method. Now it has me thinking about other ways to do it as well... namely, I wonder how the performance would compare to creating a ViewNavigator and calling .gotoEntry(doc). That's always seemed like a bizarre method to me, but I think I found it to be surprisingly fast when I tried it a while back.

I also kind of wonder how it would work in oddball scenarios like a document qualifying for the selection formula but not visually showing up in the view because its parent isn't there.

Oooh, hadn't thought of that approach. Surely it would be slower to find the document in a ViewNavigator though!? Or would it depend on the complexity of the Selection Formula. If the formula were simply SELECT Form="Foo" then evaluate may win? If the formula were dozens of lines of code, perhaps not?

Another approach, which would work the same way for both views and folders is to create an empty NoteCollection object, use NoteCollection.add(doc) to put your document into the collection, and then use NoteCollection.intersect(view). If your document is still in the NoteCollection, it was in the view.

Or to do it in bulk instead of one document at a time, first define two NoteCollection objects nc1 and nc2, with both containing all documents using the setSelectDocuments(true) and buildCollection() methods. Next call nc2.intersect(view) which gives you only the documents in the view. Finally, call nc1.remove(nc2), which gives you all the documents that were not in the view.

If you have multiple views and/or folders to work with, you can do it in a loop. I.e., after each remove(), call nc2.clearCollection, then call nc2.add(nc1) so once again you have two identical collections (all docs minus the ones that were removed in previous iterations), and repeat the process of intersecting and removing.

Note that I haven't tried the bulk approach, but I have a feeling it should be significantly faster because it's never actually opening documents.