如何创建类似于三个不同类型列表的笛卡尔积的数据结构? [英] How to create a data structure similar to the cartesian product of three lists of different types?

查看:40
本文介绍了如何创建类似于三个不同类型列表的笛卡尔积的数据结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个类似于三个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:

  1. List< String>措施
  2. List< Type>类型
  3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆