简体   繁体   English

如何从 LinkedHashMap 的值进行组合<string, arraylist<arraylist> ></string,>

[英]How to make combination from values of of LinkedHashMap<String, ArrayList<ArrayList>>

Suppose we have below LinkedHashMap<String, ArrayList<ArrayList>>假设我们有下面的 LinkedHashMap<String, ArrayList<ArrayList>>

    {FRA=[[1, 2], [3, 4]], MEL=[[5, 6]]}

The output should be output 应该是

    [1,2,5,6], [3,4,5,6]

Similarly if input is:同样,如果输入是:

    {SFO=[[1]], SEA=[[2], [3], [4]], PHX=[[5], [6]]}

Then expected output is然后预计 output 是

    [1,2,5],[1,2,6],[1,3,5],[1,3,6],[1,4,5],[1,4,6]

I have tried below code, but did not get the expected result.我试过下面的代码,但没有得到预期的结果。

    public static ArrayList<List<String>> getCombinations(ArrayList<ArrayList<String>> valueSetList) {
    int comboCount = 1;
    for (List<String> valueSet : valueSetList)
        comboCount = Math.multiplyExact(comboCount, valueSet.size()); // Fail if overflow
    ArrayList<List<String>> combinations = new ArrayList<>(comboCount);
    for (int comboNumber = 0; comboNumber < comboCount; comboNumber++) {
        List<String> combination = new ArrayList<>(valueSetList.size());
        int remain = comboNumber;
        for (List<String> valueSet : valueSetList) {
            combination.add(valueSet.get(remain % valueSet.size()));
            
            remain /= valueSet.size();
        }
        combinations.add(combination);
    }
    return combinations;
}

Any help is highly appreciated.非常感谢任何帮助。

The following recursive solution is based on Philipp Meister's answer to similar question about building of the Cartesian product :以下递归解决方案基于Philipp Meister对有关构建笛卡尔积的类似问题的回答:

static List<List<Integer>> merge(List<List<List<Integer>>> lists) {
    List<List<Integer>> resultLists = new ArrayList<>();
    if (lists.size() == 0) {
        resultLists.add(new ArrayList<>());
    } else {
        List<List<Integer>> firstList = lists.get(0);
        List<List<Integer>> remainingLists = merge(lists.subList(1, lists.size()));
        for (List<Integer> first : firstList) {
            for (List<Integer> remaining : remainingLists) {
                List<Integer> resultList = new ArrayList<>();
                resultList.addAll(first);
                resultList.addAll(remaining);
                resultLists.add(resultList);
            }
        }
    }
    return resultLists;
}  

Main difference is in the return type and adding all elements of the first list to the nested list according to the requirements.主要区别在于返回类型和根据要求将first列表的所有元素添加到嵌套列表中。

Test setup测试设置

private static void testCombinations(Map<String, List<List<Integer>>> map) {
    System.out.println("input map: " + map);
    
    List<List<Integer>> list = merge(new ArrayList<>(map.values()));
    
    list.forEach(System.out::println);
}

// --------
Map<String, List<List<Integer>>> map1 = new LinkedHashMap<>();

map1.put("SFO", Arrays.asList(Arrays.asList(1)));
map1.put("SEA", Arrays.asList(Arrays.asList(2), Arrays.asList(3), Arrays.asList(4)));
map1.put("PHX", Arrays.asList(Arrays.asList(5), Arrays.asList(6)));

testCombinations(map1);
        
Map<String, List<List<Integer>>> map2 = new LinkedHashMap<>();

map2.put("FRA", Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3, 4)));
map2.put("MEL", Arrays.asList(Arrays.asList(5, 6)));
testCombinations(map2);

Output: Output:

input map: {SFO=[[1]], SEA=[[2], [3], [4]], PHX=[[5], [6]]}
[1, 2, 5]
[1, 2, 6]
[1, 3, 5]
[1, 3, 6]
[1, 4, 5]
[1, 4, 6]
input map: {FRA=[[1, 2], [3, 4]], MEL=[[5, 6]]}
[1, 2, 5, 6]
[3, 4, 5, 6]

The solution may be implemented using streams and recursive flatMap chain (on the basis of Marco13's answer ):该解决方案可以使用流和递归flatMap链来实现(基于Marco13 的回答):

static <T extends List> Stream<List<T>> ofCombinations(List<? extends Collection<T>> mapValues, List<T> current) {
    return mapValues.isEmpty() ? Stream.of(current) :
        mapValues.get(0).stream().flatMap(list -> {
            List<T> combination = new ArrayList<T>(current);
            combination.addAll(list);
            return ofCombinations(mapValues.subList(1, mapValues.size()), combination);
        });
}

private static void testStreamCombinations(Map<String, List<List<Integer>>> map) {
    System.out.println("input map: " + map);
    
    ofCombinations(new ArrayList<>(map.values()), Collections.emptyList())
        .forEach(System.out::println);   
}

// invoking test method
testStreamCombinations(map1);
testStreamCombinations(map2);

Test output: same as above.测试output:同上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何对LinkedHashMap Arraylist的Arraylist进行排序 <LinkedHashMap<String,String> ? - How to sort Arraylist of LinkedHashMap Arraylist<LinkedHashMap<String,String>? 如何对ArrayList进行排序 <LinkedHashMap<String,String> &gt;按键? - How to sort ArrayList<LinkedHashMap<String,String>> by key? LinkedHashMap与ArrayList-如何加载ArrayList? - LinkedHashMap with ArrayList - How to load ArrayList? 从LinkedHashMap中将地图值提取为ArrayList - Extracting map values as ArrayList from LinkedHashMap 如何制作一个ArrayList来解决LinkedHashMap的“问题”? - how make an ArrayList to solve the “issue” with LinkedHashMap? 如何转换ArrayList <LinkedHashMap<String, Comparable> &gt;可比? - How to cast ArrayList<LinkedHashMap<String, Comparable>> to Comparable? 如何从 ArrayList 存储字符串值<String>到一个 ArrayList<Object> 对象 - How to store String values from an ArrayList<String> to an ArrayList<Object> of Objects 如何从ArrayList获取值 <Hashtable<String, ArrayList<String> &gt;&gt; - how to get values from an ArrayList<Hashtable<String, ArrayList<String>>> 如何在Java中将LinkedHashMap的数组列表存储为LinkedHashMap的值 - How to store arraylist of LinkedHashMap as value of LinkedHashMap in java 如何检查Arraylist中的两个String值是否包含在另一个Arraylist中? - How to check if two String values from an Arraylist are contained in another Arraylist?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM