🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Collections
This page was created by Lars.olofsson on 2023-04-05. Last edited by Wikiadmin on 2026-07-29.

You can use collections in OCL and the Action Editor to find, filter, compare, display, and, for model objects, update groups of values or objects.

What is a collection?

A collection is a group of items treated as one value. In MDriven, a collection can contain raw values, such as numbers and strings, or instances of a modeled class.

For example, a FruitBowl can have a collection of Fruit objects. A ViewModel nesting can use that collection to render a grid of the fruits in the bowl.

Collections are central to:

Collection types

MDriven OCL works with collection types including sets, bags, and sequences. Choose the type based on whether repeated items and order matter.

Type Meaning Example
Set A collection with one instance of each item. Repeated items produced by an operation are removed. Set{1,2,3}
Bag A collection that can contain multiple instances of the same item. Bag{1,2,3}
Sequence A collection type available in OCL collection expressions. Use a sequence when the expression or result requires sequence behavior.

For the detailed distinction between sets and bags, including how duplicate results are handled, see Documentation:Set vs bag.

Transform raw-data collections with OCL

OCL is a functional, transformative language: it takes an input and returns a result. Standard OCL does not mutate raw-data collection values. Instead, write an expression that returns the collection you need.

For example, to retain only odd numbers from a collection, use select to return a new collection containing the matching values. The original collection remains unchanged.

Set{1,2,3,4,5}->select(n | n mod 2 = 1)

The result contains 1, 3, and 5.

Remove items by returning the difference

Do not rely on an in-place ->add operation to change raw data. Collection operators such as ->add can be accepted in the Action Editor, but using them on raw data produces a result that can be unexpected. Prefer an expression that explicitly produces the required output.

Use difference when you want all items in the first collection except items found in the second collection.

Set{1,2,3,4,5}->difference(Set{1,2,3})

This returns 4 and 5. The source collection is not changed.

For operator behavior and further examples, see Documentation:OCLOperators difference. To return items that occur in either collection but not both, use symmetricDifference.

Compare two collections

A symmetric difference returns the objects present in one collection or the other, but not in both. This provides a useful equality test: if the symmetric difference is empty, the two collections contain the same objects.

For example, compare two collections of Thing objects that may share some objects. An empty symmetric difference means there is no object exclusive to either collection. See Documentation:OCLOperators symmetricDifference.

Work with collections of model objects

Collections of modeled class objects can be both queried and changed in the Action Editor. Associations are the most common mutable collections.

For example, a Category can have a Products association. If that association is a Set, a Product object can occur only once in the association link. Add or remove the association link in an Action Editor action when you need to change which products belong to the category.

You can also query a class collection in OCL. The following expression starts with every Product instance and returns only products whose Price is greater than 1000:

Product.allInstances->select(p | p.Price > 1000)

The expression returns a collection; it does not change any Product object. Use a modeled association as the starting collection when the query should be restricted to one category's products.

Raw values and class objects: the practical difference

Situation What you can do Example
Raw-data collection in OCL Transform it into a new collection; do not expect the original value to be mutated. Filter Set{1,2,3,4,5} to return only odd values.
Collection of model objects in an Action Editor action Query it, transform it, and update association collections as part of the action. Add a Product object to a Category's Products association.
Collection of model objects in an OCL expression Query and transform it without changing the model objects. Select Products whose Price is greater than 1000.

Show a collection in a ViewModel

Use a nested ViewModel clause when an expression returns a collection of model objects. MDriven can render the resulting collection as a data grid.

For example, to show the other Fruit objects in the same FruitBowl:

  1. Add a nesting to the ViewModel.
  2. Set the nesting expression to the collection that identifies the fruits in the same bowl.
  3. Set the nesting type to Fruit.
  4. Add the Fruit attributes that you want as grid columns.
  5. If the current Fruit should not appear in the grid, filter the collection with an expression such as Fruits->select(f | f <> self).

The ViewModel maintains a current variable for a nesting, so actions or expressions can use the object currently selected by the user in that grid. This is useful when a user selects one Fruit and you need to show or act on a property of that Fruit.

Collections of enumeration values

Enumeration values are represented as tuples in the model type system. Collection membership checks for enumerations require a selection expression rather than includes.

For example, to check whether an active user's UserModes collection contains #Consultant:

SysSingleton.SO.ActiveUser.UserModes->select(x | x = #Consultant)->notEmpty

See Documentation:Enumerations for enumeration collections, string conversion, and ordinal lookup.

Tips

  • Start with the collection you actually need. For related objects, navigate the association rather than querying all instances and filtering afterward.
  • Use select to filter and return a new result collection.
  • Use difference to exclude objects or values without mutating the input collection.
  • Use a Set for an association when duplicate links must not occur; see Documentation:Set vs bag.
  • Keep OCL expressions transformative. Put intentional model updates in the Action Editor.

See also