In Part 1 of this series of article about the Finder interface, I have introduced the most common way to start a search. With this article I would like to have a closer look on what to do with the result, more specifically, how to iterate over the found objects.
One Element Expected
In case the script expects just a single match, it can use the methods "isEmpty()", and "first()". The first obviously returns true if no object was found, the second returns the firs object found or "undefined" if there was no match. An example:
var result = finder.findByType(Metamodel.sysml.SysMLPart);
if (result.isEmpty()) {
throw "No part found in your project - bail out";
}
alert("Part name is " + result.first().name);
// alternative
var part = finder.findByType(Metamodel.sysml.SysMLPart).first();
alert("Part name is " + (part ? part.name : "undefined"));
Multiple Elements Expected
If the script expects multiple elements and wants to iterate over all found elements, it ma utilize either "asList()" or "asArray()" to convert it to the respective collection types or directly iterate using "forEach(...)". Alternatively the script may iterate over the result type as well, utilizing "size()".
Again an example for each of the possibilities:
var result = finder.findByType(Metamodel.sysml.SysMLPart).asArray();
for (var i = 0; i < result.length; i++) {
var part = result[i];
console.log("Part {0} is {1}", i, part.name);
// TODO ...
}
// alternative (no variable i)
result.forEach(function (part) {
console.log("Part is {0}", part.name);
// TODO ...
});
Now using "forEach()" directly on the result:
finder.findByType(Metamodel.sysml.SysMLPart).forEach(function (part) {
console.log("Part is {0}", part.name);
// TODO ...
});
The advantage of using "forEach()" is probably the short code, no need to explicitly iterate using a for loop. Disadvantage is that you cannot stop the iteration, there is no "break" statement or similar concept and that there is no iterator as for the for loop, so the loop code does not know the index of the element.
There are use cases for both ways, choose the one that fits best.
Note that the following code does not work for some incompatibility between the JS engine and Java Generics for Collections:
// forEach for Lists does not work
result.asList().forEach(function (part) {
console.log("Part is {0}", part.name);
// TODO ...
});
Comments are as usual welcome,
Happy Scripting
Jan