如何创建类似于三个不同类型列表的笛卡尔积的数据结构? [英] How to create a data structure similar to the cartesian product of three lists of different types?
问题描述
我想创建一个类似于三个List的笛卡尔乘积的DataStructure.我还通过 Jurgen 提出了现有答案,建议使用flatMap.我也尝试过这种方式.但是我已经确定 filterValue
列表位于 types
列表内.因此,flatMap在这里不起作用.由于 filterValues
可以为 0或更多
.因此,根据笛卡尔乘积(我们可以称其为组合),它会发生变化.
I want to create a DataStructure which will be similar to the cartesian product of three List.
I've also referred the existing answer by Jurgen which suggest to use flatMap. I tried in that way as well. But I've condition that filterValue
list is inside types
list. So flatMap will not work here. As filterValues
can be 0 or more
. So depending on that cartesian product (we might call it as combination) will change.
度量,类型和内容的大小每个列表的filterValues
可以不同.如果 measure
列表为空.然后,该组合将仅是类型和&filterValues
(和 measure
将设置为 null
.我在 if-else
块的注释中添加了这些不同的方案
Size of measures, types & filterValues
can be different for each list.
If measure
list is empty. Then the combination will be of only types & filterValues
(and measure
will be set to null
. I've added these different scenarios in my comments of if-else
block
我有以下几种类型的列表:
I've following types of list:
-
List< String>措施
-
List< Type>类型
-
List< FilterValue>filterValues
例如,输入结构为:
{
"measures": [
"m1",
"m2",
"m3"
],
"types": [
{
"type": "type-1",
//some more fields
"filterValues": [
//no filter values present
]
},
{
"type": "type-2",
//some more fields
"filterValues": [
{
"filterValue": "t2f1"
//some more fields
},
{
"filterValue": "t2f2"
//some more fields
}
]
}
]
}
然后在上述情况下,我期望的输出数据结构是
Then in above case the output data structure I'm expecting is
m1 type-1 null
m1 type-2 t2f1
m1 type-2 t2f2
m2 type-1 null
m2 type-2 t2f1
m2 type-2 t2f2
m3 type-1 null
m3 type-2 t2f1
m3 type-2 t2f2
然后将相同的上述值设置为以下类别:
Then the same above values I'm setting into the following classes:
class SearchArea {
String measure;
String type;
TypeCombi typeFileter;
//constructor for measure & type
//constructor for all three
//getters & setters
}
class TypeCombi {
String type;
String name; //it is mapped with filterValue
//constructor for above two fields
//getters & setters
}
类 Type
& FilterValue
如下
class Type {
String type;
List<FilterValue> filterValues;
//some more fields
//getters and setters
}
class FilterValue {
String filterValue;
//some more fields
//getters and setters
}
我可以使用以下 getSearchAreas
函数获得预期的输出.但是在这种情况下,我使用了多个(两个) for
循环.可以使用 stream/flatmap
而不是两个 for循环
清除此代码块吗?还有没有更好的方法来处理多个if/else块?(我已经在每种if/else块上方添加了注释)
I'm able to achieve the expected output using following getSearchAreas
function. But in this case I'm using multiple(two) for
loops. Can this code block cleaned up using stream/flatmap
instead of two for loops
?
Also is there any better way to handle multiple if/else block ?(I've added comment above each if/else block for it's scenario)
private List<SearchArea> getSearchAreas(List<String> measures, List<Type> types){
List<SearchArea> searchAreas = new ArrayList<>();
//measures & types both are empty
if ((measures == null || measures.isEmpty())
&& (types == null || types.isEmpty()))
return Collections.emptyList();
//one or more measure and zero types
else if (measures != null && !measures.isEmpty()
&& (types == null || types.isEmpty())) {
searchAreas = measures
.stream()
.map(measure -> new SearchArea(measure, null))
.collect(Collectors.toList());
return searchAreas;
}
//zero measures and one or more types
else if ((measures == null || measures.isEmpty())) {
for (type type : types) {
if (type.getFilterValues() == null
|| type.getFilterValues().isEmpty()) {
searchAreas.add(new SearchArea(null, type.getType()));
} else {
searchAreas.addAll(type.getFilterValues()
.stream()
.map(filterValue -> new SearchArea(null,
type.getType(),
new TypeCombi(type.getType(),
filterValue.getFilterValue())))
.collect(Collectors.toList()));
}
}
return searchAreas;
}
//one or more measures and one or more types
else {
for (String measure : measures) {
for (Type type : types) {
if (type.getFilterValues() == null
|| type.getFilterValues().isEmpty()) {
searchAreas.add(new SearchArea(measure, type.getType()));
} else {
searchAreas.addAll(type.getFilterValues()
.stream()
.map(filterValue -> new SearchArea(measure,
type.getType(),
new TypeCombi(type.getType(),
filterValue.getFilterValue())))
.collect(Collectors.toList()));
}
}
}
return searchAreas;
}
}
如果有人能以清洁的方式帮助我进行上述重组,那就太好了.
It will be great if someone can help me in restructuring above in cleaner fashion.
推荐答案
我认为这就是您想要的.请注意,有时不使用流会更干净.
I think this is what you want. Note that it is sometimes cleaner not to use streams.
public static void main(String[] args) throws Exception {
List<String> strings = Collections.emptyList();
List<Integer> ints = Arrays.asList(1, 2, 3);
if (strings == null || strings.isEmpty()) {
strings = Collections.singletonList(null);
}
if (ints == null || ints.isEmpty()) {
ints = Collections.singletonList(null);
}
for (String str : strings) {
for (Integer integer : ints) {
// In your code doubles comes from a property of integer.
List<Double> doubles = integer == null ? Collections.emptyList() : Arrays.asList(1.0d, 2.0d, 3.0d);
if (doubles == null || doubles.isEmpty()) {
doubles = Collections.singletonList(null);
}
for (Double doubler : doubles) {
// Create your object here.
System.out.format(Locale.US, " str = %s, int = %d, double = %f %n", str, integer, doubler);
}
}
}
}
输出如下:
str = null, int = 1, double = 1.000000
str = null, int = 1, double = 2.000000
str = null, int = 1, double = 3.000000
str = null, int = 2, double = 1.000000
str = null, int = 2, double = 2.000000
str = null, int = 2, double = 3.000000
str = null, int = 3, double = 1.000000
str = null, int = 3, double = 2.000000
str = null, int = 3, double = 3.000000
这篇关于如何创建类似于三个不同类型列表的笛卡尔积的数据结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!