Найти декартово произведение двух списков с помощью Apache Beam w java

У меня 2 коллекции

      PCollection<List<String>> ListA = pipeline.apply("getListA", ParDo.of(new getListA()))
PCollection<List<String>> ListB = pipeline.apply("getListB", ParDo.of(new getListB()))

ListA содержит

      ["1","2","3"]

ListB содержит

      ["A","B","C"]

Как мне получить коллекцию PCollection, содержащую

      [
 ["A","1"],["A","2"],["A","3"],
 ["B","1"],["B","2"],["B","3"],
 ["C","1"],["C","2"],["C","3"],
]

Мой поиск указал мне на

Как сделать декартово произведение двух коллекций PCollections в потоке данных?

но это имеет дело с KV с использованием coGroupby с 2 выходами. Возможно, что coGroupby можно использовать для создания декартового произведения двух списков, но я этого не вижу.

2 ответа

Вы можете использовать Java 8 Stream.reduce метод следующим образом:

      List<String> listA = Arrays.asList("1", "2", "3");
List<String> listB = Arrays.asList("A", "B", "C");
      List<List<String>> cartesianProduct = Stream.of(listA, listB)
        // represent each list element as a singleton list
        .map(list -> list.stream().map(Collections::singletonList)
                .collect(Collectors.toList()))
        // summation of pairs of inner lists
        .reduce((list1, list2) -> list1.stream()
                // combinations of inner lists
                .flatMap(inner1 -> list2.stream()
                        // merge two inner lists into one
                        .map(inner2 -> new ArrayList<String>() {{
                            addAll(inner1);
                            addAll(inner2);
                        }}))
                // list of combinations
                .collect(Collectors.toList()))
        // List<List<String>>
        .orElse(Collections.emptyList());
      // output
System.out.println(cartesianProduct);
//[[1, A], [1, B], [1, C], [2, A], [2, B], [2, C], [3, A], [3, B], [3, C]]

См. Также: Как создать декартово произведение с потоками Java 8?

Похоже, что у вас есть один элемент в каждой коллекции PCollection, поэтому вам просто нужно объединить эти элементы, а затем вы можете самостоятельно выполнить декартово произведение в DoFn

Что-то вроде

      Flatten.pcollections(ListA, List)
.apply(WithKeys.of(null))
.apply(GroupByKey.create())

После этого у вас будет PCollection с одним элементом, которым является KV (null, Iterable (ListA, ListB)), и вы можете сгенерировать декартово произведение с некоторыми циклами for.

Другие вопросы по тегам