我有一个数组列表,其中包含(I)ndex、(C)ategory、(S)ubcategory和(V)value。
I C S V
0 1 1 A
1 1 1 B
2 1 2 C
3 1 3 D
4 1 3 E
5 2 1 F
6 2 1 G
7 2 2 H
8 2 J
我需要处理AB,然后是C,然后是DE。然后处理AB+C+DE,重复操作2,依此类推。最后用写一个输出文件
AB+C+DE
FG+HJ
请不要将*
和+
字面上解释为乘积和总和。
public void translate(List<String[]> raw) {
int oldCategory = 0;
int newCategory = 0;
int oldSubCategory = 0;
int newSubCategory = 0;
boolean keepWorking = true;
do {
oldCategory = newCategory;
newCategory = getNewCategory(oldCategory, raw); //get end of category. Now it returns 5, then 9.
do {
oldSubCategory = newSubCategory;
newSubCategory = getNewSubCategory(oldSubCategory, raw);
List<String> products = doFirstOperation(raw, oldCategory, newCategory, oldSubCategory, newSubCategory); //A*B, D*E, etc.
} while (newSubCategory< newCategory);
doSecondOperation(products); // compute "A*B+C+D*E" and append it to file
} while (newCategory < raw.size());
}
如果当前类别是最后一个,则getNewCategory(oldCategory, raw)
返回新类别或数组.size()中第一个元素的索引。在当前的设置中,我通常在Category的范围之外设置newSubCategory。这是在请求一个ArrayIndexOutOfBoundsException。我可以使用令牌boolean isLastCategory
、dowhile(!isLastCategory)并返回newCategory作为给定类别中最后一个元素的索引,但这看起来很庞大。
组织这样的代码的好方法是什么?
这种模式在某些地方被称为"级联报告中断"。这里有一种可能的方法,在伪代码中:
curCat = null
curSub = null
while rec = read()
if (rec.cat != curCat)
if (curCat != null)
endCat()
startCat()
else if (rec.sub != curSub)
endSub()
startSub()
accumulate rec
end while
if (curCat != null)
endCat()
function startCat()
curCat = rec.cat
initialize cat accumulator
startSub()
function startSub()
curSub = rec.sub
initialize sub accumulator
function endSub()
finalize subcategory
function endCat()
endSub()
finalize category
如果你不喜欢空检查浪费(它们只适用于文件的开头),你可以使用以下替代方法:
rec = read()
if (!EOF)
startCat()
while rec = read()
if (rec.cat != curCat)
endCat()
startCat()
else if (rec.sub != curSub)
endSub()
startSub()
accumulate rec
end while
endCat()
根据OOP的性质和封装需要进行调整。
顺便说一句,这可以追溯到20世纪60年代和COBOL报告编写程序,但仍然是将嵌套中断和累积概念化的一种巧妙方式。
如果您使用Java8,以下是实现的方法
List<Model> models = new ArrayList<>();
models.add(new Model("0", "1", "1", "A"));
models.add(new Model("1", "1", "1", "B"));
models.add(new Model("2", "1", "2", "C"));
models.add(new Model("3", "1", "3", "D"));
models.add(new Model("4", "1", "3", "E"));
models.add(new Model("5", "2", "1", "F"));
models.add(new Model("6", "2", "1", "G"));
models.add(new Model("7", "2", "2", "H"));
models.add(new Model("8", "2", "2", "J"));
Map<String, Map<String, List<Model>>> map = models.stream()
.collect(groupingBy(Model::getCategory, groupingBy(Model::getSubCategory)));
List<String> strings = map.values().stream()
.map(submap -> submap.values().stream()
.map(list -> list.stream().map(Model::getValue).collect(joining("*"))).collect(joining("+")))
.collect(toList());
System.out.println(strings);
输出
[A*B+C+D*E, F*G+H*J]