Reputation: 249
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?
Upvotes: 2
Views: 4998
Reputation: 9380
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
Upvotes: 5
Reputation: 116714
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).
Upvotes: 1