Dynamically create loops to iterate over a List of List<String>'s

爷,独闯天下 提交于 2019-12-24 03:43:27

问题


I have a List of List<String>'s which I get from a external API method call:

List<List<String>> outerList

I have to create unique key combinations by concatenating strings from each list in the same order they are in the outer list.

Example: If outer list has 2 inner lists, say list1: {"A","B"} and list2: {"C","D"}. Then possible unique combinations will be AC, AD, BC and BD.

But the problem is the outerList size is dynamic, it can contain any number of inner lists. If the inner list numbers are fixed then I can write for loops and create combinations.

I am thinking in the direction of using reflections, recursion etc but so far have not been able to solve it.

public static void main(String[] args) {

    List<List<String>> outerList = new ArrayList<List<String>>();
    List<String> list1 = new ArrayList<String>();
    list1.add("A");
    list1.add("B");
    List<String> list2 = new ArrayList<String>();

    list2.add("C");
    list2.add("D");
    outerList.add(list1);

    outerList.add(list2);

    for(String s1: list1) {
        for(String s2: list2) {
            System.out.println(s1+s2);
        }
    }
}

Here outerList has 2 inner lists so I have created 2 for loops explicitly to iterate and concatenate. But in real-time outerList can have any number of inner lists, how to loop dynamically loop through all the inner loops and concatenate?


回答1:


This code works for me:

public class Test
{  

    public static void generate(LinkedList<LinkedList<String>> outerList, String outPut) {
        LinkedList<String> list = outerList.get(0);

        for(String str : list) {
            LinkedList<LinkedList<String>> newOuter = new LinkedList<LinkedList<String>>(outerList);
            newOuter.remove(list);

            if(outerList.size() > 1) {
                generate(newOuter, outPut+str);
             } else {
               System.out.println(outPut+str);
             }
        }
    }

    public static void main(String[] args) 
    {
        LinkedList<LinkedList<String>> outerList = new LinkedList<LinkedList<String>>();

        LinkedList<String> list1 = new LinkedList<String>();
        LinkedList<String> list2 = new LinkedList<String>();

        list1.add("A");
        list1.add("B");

        list2.add("C");
        list2.add("D");

        outerList.add(list1);
        outerList.add(list2);

        Test.generate(outerList, "");
    }      
}

Output:

AC
AD
BC
BD




回答2:


Sample data with enough variation to demonstrate the problem:

    List<List<String>> outerList = new ArrayList<List<String>>();

    List<String> innerList1 = new ArrayList<String>();
    innerList1.add("A");
    innerList1.add("B");
    outerList.add(innerList1);

    List<String> innerList2 = new ArrayList<String>();
    innerList2.add("X");
    innerList2.add("Y");
    innerList2.add("Z");
    outerList.add(innerList2);

    List<String> innerList3 = new ArrayList<String>();
    innerList3.add("P");
    innerList3.add("Q");
    innerList3.add("R");
    outerList.add(innerList3);

Keep an array of counters:

    int[] positions = new int[outerList.size()];

    boolean another = true;
    while (another) {
        for (int n = 0; n < outerList.size(); n++) {
            System.out.print(outerList.get(n).get(positions[n]));
        }
        System.out.println();

        another = false;
        for (int c = 0; c < outerList.size(); c++) {
            positions[c]++;
            if (positions[c] < outerList.get(c).size()) {
                another = true;
                break;
            }
            positions[c] = 0;
        }
    }

Each time around the main loop, I print one item from each inner list. Then I advance the counters, starting with the first. If that doesn't go off the end of the first inner list, we're ready to print again. But if it does, I set that counter to zero and try advancing the second one, and so on. If they all wrap round to zero, it's time to quit.

It's really just like counting except that the columns each have a different "base" (instead of all being base ten or two or whatever).



来源:https://stackoverflow.com/questions/7698008/dynamically-create-loops-to-iterate-over-a-list-of-liststrings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!