In programming, a collection is a class used to represent a set of similar data type items as a single unit. These unit classes are used for grouping and managing related objects. A collection has an underlying data structure that is used for efficient data manipulation and storage. Read more here: What Does Collection Mean?
A set and a bag are both collections of items in programming, but they differ in their characteristics and behaviors.
- A set is a collection of distinct and unordered elements - each item can only appear once in the collection. Sets are commonly used when the order of elements is unimportant, but uniqueness is. In sets, duplicates are not allowed, and any attempts to add an already existing item are simply ignored. Sets are usually implemented using hash tables, which provide efficient membership testing and set operations such as union, intersection, and difference.
- A bag, also known as a multiset, is a collection of elements that allows duplicates and does not impose any order on the items. In a bag, elements can appear multiple times, and the count of each item represents the number of times it occurs in the collection. Bags are useful when we need to keep track of the frequency of occurrence of each element. For example, a bag can be used to store a histogram of a set of values. Bags are typically implemented using arrays or hash tables, where each element is associated with a count.
Immutable Collections
Raw data in OCL collections uses standard OCL which does not allow mutation of the different collection type objects (Sets, Bags, Sequences). The collections cannot be changed but they can be manipulated and transformed to achieve a desired output with a new collection.
NOTE: Using collection OCL operators like ->add
on raw data will still work in the Action Editor but result in a peculiar output.
Examples
1. Get all prime numbers between 2 and 100
Sequence{2..100}->select(n|
Sequence{2..n-1}-> forAll(i| (n-((n/i).Floor*i))<>0)
)
Returns
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
2. Get all odd numbers and even numbers between 1 and 100
let evenNumbers = Sequence{1..100}->select(n| (n-((n/2).Floor*2)) = 0) in
(
let oddNumbers = Sequence{1..100}->select(n| (n-((n/2).Floor*2)) <> 0) in
(
oddNumbers->union(evenNumbers)
)
)
Returns
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100]
3. Remove the elements 1,2 and 3 from a collection. Existing OCL expressions can always be used to transform a collection to achieve the desired output. For this case, the difference OCL operator can be used to remove elements from a collection since it returns all the elements that are in the first collection only, exclusive of the second collection.
Bag{1,2,3,4,5}->difference(Bag{1,2,3})
Returns
[4,5]
Mutable Collections
Class object collections in MDriven can be changed and updated in the Action Editor. With classes, you get the ability to not only mutate collections but also transform the collections.
Most common mutations on collections are with associations.
Example
1. How to create a category with products in OCL. Products are added to the Category object using the Products association attribute which is a Set collection to ensure there are no duplicate copies of Product objects in the association link.
let category = Category.Create in
(
category.Name:='Fashion';
let product1 = Product.Create in
(
product1.Name:='Jeans';
product1.Description:='Blue jeans';
product1.Price:=1200;
product1.DateAdded:=DateTime.Now ;
category.Products->add(product1)
);
let product2 = Product.Create in
(
product2.Name:='Polo T-Shirt';
product2.Description:='V-Neck Polo T-shirt, Color: blue';
product2.Price:=1200;
product2.DateAdded:=DateTime.Now ;
category.Products->add(product2)
)
);
selfVM.Save
2. Class objects collection expressions in MDriven are used to query the database.
i) How to get the sum of all product prices of a specific category
Category.allinstances->select(q|q.Name='Fashion')->collect(c|c.Products.Price)->sum
ii) How to get the Products whose Price is greater than 1000
Product.allinstances->select(q|q.Price > 1000)
Conclusion
- Collections are immutable when working with raw data.
- Collections are mutable when working with class objects in the Action Editor.
- Use existing expressions creatively to achieve the desired output.