Skip to content

Commit

Permalink
[Operator] add cartesian_product operator to combine a list of lists
Browse files Browse the repository at this point in the history
  • Loading branch information
chapuisk committed Jul 15, 2021
1 parent 335f921 commit feb95e0
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
28 changes: 28 additions & 0 deletions msi.gama.core/src/msi/gaml/operators/Containers.java
Expand Up @@ -18,8 +18,11 @@
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
Expand All @@ -32,6 +35,7 @@
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

import msi.gama.common.interfaces.IGamlIssue;
import msi.gama.common.interfaces.IKeyword;
Expand All @@ -55,6 +59,7 @@
import msi.gama.runtime.GAMA;
import msi.gama.runtime.IScope;
import msi.gama.runtime.exceptions.GamaRuntimeException;
import msi.gama.util.Collector;
import msi.gama.util.GamaColor;
import msi.gama.util.GamaListFactory;
import msi.gama.util.GamaListFactory.GamaListSupplier;
Expand Down Expand Up @@ -1318,6 +1323,29 @@ public static double sum(final IScope scope, final IGraph g) {
if (g == null) return 0.0;
return g.computeTotalWeight();
}

@operator (
value = "cartesian_product",
//can_be_const = true,
doc = @doc ("Returns the cartesian product of elements in all given sub-lists"),
expected_content_type = { IType.LIST },
category = { IOperatorCategory.CONTAINER },
concept = { IConcept.CONTAINER }
)
@test ("cartesian_product([['A','B'],['C','D']]) = [['A','C'],['A','D'],['B','C'],['B','D']]")
public static Object cart_prod(final IScope scope, final IList list) {
IType ct = list.getGamlType().getContentType();
if (!ct.isContainer()) { GamaRuntimeException.error("Must be a list of list", scope); }

final IList<IList> l = notNull(scope, list).listValue(scope, list.getGamlType().getContentType(), false);
List<? extends Set<Object>> setOfSet = l.stream(scope).map(ilist -> new LinkedHashSet<>(ilist)).collect(Collectors.toList());

IList<IList> res = GamaListFactory.create(ct);
Set<List<Object>> cp = Sets.cartesianProduct(setOfSet);
for (List cartList : cp) { res.add(GamaListFactory.create(scope, ct.getContentType(), cartList)); }

return res;
}

@operator (
value = { "sum_of" },
Expand Down
Expand Up @@ -134,6 +134,7 @@ species accessing_list_elements {
species combining_lists {
list<int> l1 <- [1,2,3,4,5,6,7,8,9,10];
list<int> l2 <- [1,3,5,7,9];
list<list> useful_list_of_lists <- [['A','B'],['C','D']];
init {
write "";
write "== COMBINING LISTS ==";
Expand All @@ -149,6 +150,7 @@ species combining_lists {
list<string> l3 <- list<string>(l1 + l2);
write "list<string> l3 <- l1 + l2; " + sample(l3);
write sample(l1 as list<float>);
write sample(cartesian_product(useful_list_of_lists));
}
}

Expand Down

0 comments on commit feb95e0

Please sign in to comment.