This function implements a more complex case of filtering elements by key (see filterElementsByKey() function).

It takes into account that those elements (GOMElement objects) from the source enumeration, which produce the same filtering key, may belong to a certain specific group so that all such elements must get into the result enumeration. That is, filtering by keys within the same group must be suppressed.

Groups are defined by another key (called group key) calculated for each element. When group keys are the same, the elements belong to the same group.

Precisely, the filtering works as follows:

  1. All element from the source enumeration are iterated.
  2. For each element, the filtering and group keys are generated using the subqueries provided in filterKeyQuery and groupKeyQuery parameters. The element is associated with those keys.
  3. By a special hashmap, the filtering key is checked if an equal filtering key has been already produced on one of the previous iterations. If not, the element is added to the result enumeration queue and the iterations proceed to the next source element.
  4. When such a filtering key has been already generated, it is looked, which queued element is associated with it, and its group key is compared with the current element's group key. If both group keys are equal, the current element is appended to the group associated with that already queued element (with the same filtering/group keys).
  5. When the group keys are different, the preference condition is tested that is calculated against the current element by the boolean subquery specified in prefCondQuery parameter.

    When that subquery is provided and it returns true, the queued element associated with the same filtering key is deleted from the result enumeration queue. The associated with it group of other elements accumulated on previous iterations is also deleted. The current element is added to the result enumeration queue.

    Otherwise, the iterations just proceed to the next source element.

  6. When all source elements have been iterated, the result enumeration is produced from consequent elements in the queue. At that, when an element has a group associated with it, all elements from that group will be added to the result enumeration immediately after that element.

    Thereby, the elements in the result enumeration may be ordered somewhat differently as in the source one – the elements with the same filtering/group keys will get grouped together.

Parameters:

sourceElements

The enumeration of source elements.

Note: If this parameter is null, the function does nothing and returns null.

filterKeyQuery
The subquery that will be execute for each source element to generate its filtering key.

The element is passed to the subquery as the generator context element. The value returned by the subquery should be an object good to be a hash key. The null value is also allowed.

The subquery may be created using FlexQuery() function.

Note: If this parameter is null, the function does nothing and returns the original enumeration.

Note: When you need to filter elements by several keys with different types so that only the whole set of keys generated for each element must be unique, you can do it by creating a single compound filtering key using HashKey() function.

groupKeyQuery
The subquery that will be execute for each source element to generate its group key.

The element is passed to the subquery as the generator context element. The value returned by the subquery should be an object good to be a hash key. The null value is also allowed.

The subquery may be created using FlexQuery() function.

Note: If this parameter is null, no grouping will be taken into account. (The result will be the same as calling filterElementsByKey() function).

Note: When the group key must consist of several keys with different types, you can make it using HashKey() function.

prefCondQuery
The boolean subquery that calculates the preference condition for the element.

When specified, this subquery will be executed for each source element whose filtering key is repeating but grouping key does not (that is, when there a queued element with the same filtering key and different group key).

The element is passed to the subquery as the generator context element.

If the subquery returns true, the queued element will be deleted from the queue (along with any group associated with it) and the current element added to the queue instead.

If the preference condition subquery is not specified (i.e. omitted or null) or returns false, the current element with the repeating filtered key will be skipped over.

The subquery may be created using BooleanQuery() function.

For example, specifying in this parameter the subquery

BooleanQuery(true)
will have the effect that for all source elements associated with the same filtering key (but different group keys), only the last of them will appear in the result enumeration.
Example:

In the following expression, an enumeration of custom elements is created by integer values specified in 'numbers' array (so that each value from the array becomes the value of a corresponding element in the enumeration). Further, that enumeration is filtered using filterElementGroupsByKey() function so that

  1. The filtering key is the decade, to which the number belongs
  2. The group key is the boolean: if the number is divisible by 3
The last collectValuesByElements() function call converts the result filtered enumeration of elements into an array of its values.

numbers = Array (12, 22, 6, 14, 15, 3, 7, 23);

e = filterElementGroupsByKey (
  toCustomElements (numbers),
  FlexQuery (toInt (contextElement.value.toInt() / 10)),
  FlexQuery (contextElement.value.toInt() % 3 == 0)
);

e.collectValuesByElements()
The evaluation of that expression will return the following array:
[ 12, 15, 22, 23, 6, 3 ]
See Also:
filterElementsByKey(), FlexQuery(), BooleanQuery(), HashKey()