我正在尝试对包含
的List<Object>
进行分组
Exercice, type, User, passed, ..
还有更多,但最重要的是,我的名单很长,所以我想按以下类别对其进行分组:
Type, User, NumberOfPassed, NumberOfFaileds
例如我有:
Exercice1, hand, Hans@gmail.com, true
Exercice2, hand, Hans@gmail.com, false
Exercice3, hand, Hans@gmail.com, false
Exercice4, hand, Hans@gmail.com, false
Exercice2, hand, Thiago@gmail.com, true
Exercice1, hand, Thiago@gmail.com, true
输出应为
Hand, Hans@gmail.com, 1/4
Hand, Thiago@gmail.com, 2/2
答案 0 :(得分:1)
我认为您可以创建此对象来帮助您解决此问题:
public class Result {
private String type;
private String email;
private int numPassed;
private Double total;
public Result(String type, String email, boolean approved) {
total = 1.0;
this.type = type;
this.email = email;
this.numPassed = approved ? 1 : 0;
}
public void increase(boolean examResult){
total++;
if(examResult){
numPassed++;
}
}
public boolean isApproved(){
return numPassed >= total / 2d;
}
public String getFraction(){
return numPassed + "/" + total.intValue();
}
}
将列表分组的算法应该是这样的:
private static List<Result> group(List<Input> yourList) {
List<Result> result = new ArrayList<>();
for (Input i : yourList) {
String type = i.getType();
String email = i.getEmail();
boolean approved = i.isApproved();
Result r = getIfExists(result, type, email);
if(r != null){
result.remove(r);
r.increase(approved);
} else{
r = new Result(type, email, approved);
}
result.add(r);
}
return result;
}
private static Result getIfExists(List<Result> results, String type, String email) {
Result result = null;
boolean exit = false;
for (int i = 0; i < results.size() && !exit; i++) {
Result r = results.get(i);
if (r.getType().equals(type) && r.getEmail().equals(email)) {
result = r;
exit = true;
}
}
return result;
}
该代码不会编译,因为它没有实现setter-getter,但是实现了它。
答案 1 :(得分:1)
鉴于您的数据类如下:
data class UserData(
val exercise: String,
val type: String,
val emailAddress: String,
val passed: Boolean
)
您可以首先使用type
作为生成地图的键,对emailAddress
和Pair
进行分组:
val groupingMap = l.groupBy{ it.type to it.emailAddress }
groupingMap
的类型为:Map<Pair<String, String>, List<UserData>>
之后,您可以像下面这样使用forEach
遍历该地图:
resultMap.forEach { (groupKey, list) ->
val numElements = list.count()
val numTrueElements = list.count { it.passed }
val (type, emailAddress) = groupKey
println("$type, $emailAddress, $numTrueElements/$numElements")
}
结果:
手,Hans @ gmail.com,1/4
手,Thiago @ gmail.com,2/2
对于type
甚至可能更适合exercise
的类型(取决于用例),但是出于示例的考虑,我选择了String
。
答案 2 :(得分:-1)
我认为您可以使用list>将对象列表分组为另一个对象列表。