Reputation: 1031
I'm trying to group a List<Object>
which contains
Exercice, type, User, passed, ..
There are more but those are the most important, the thing is that I'm getting a long list, so I want to group it by :
Type, User, NumberOfPassed, NumberOfFaileds
For instance I have :
Exercice1, hand, [email protected], true
Exercice2, hand, [email protected], false
Exercice3, hand, [email protected], false
Exercice4, hand, [email protected], false
Exercice2, hand, [email protected], true
Exercice1, hand, [email protected], true
And the output should be
Hand, [email protected], 1/4
Hand, [email protected], 2/2
Upvotes: 0
Views: 948
Reputation: 29844
Given your data class looks like this:
data class UserData(
val exercise: String,
val type: String,
val emailAddress: String,
val passed: Boolean
)
You could first group by type
and emailAddress
using a Pair
as key for the resulting map:
val groupingMap = l.groupBy{ it.type to it.emailAddress }
groupingMap
will be of type: Map<Pair<String, String>, List<UserData>>
After that you can iterate over that map using forEach
like this:
resultMap.forEach { (groupKey, list) ->
val numElements = list.count()
val numTrueElements = list.count { it.passed }
val (type, emailAddress) = groupKey
println("$type, $emailAddress, $numTrueElements/$numElements")
}
Result:
hand, [email protected], 1/4
hand, [email protected], 2/2
There might be better suited types for type
and maybe even exercise
(it depends on the use-case) but for the sake of the example I chose String
.
Upvotes: 2
Reputation: 105
I think you could create this object to help you to solve this:
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();
}
}
And the algorithm to aggroup your list should be like this:
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;
}
This code won't compile since is not implemeting setter-getter but implemeting it will work.
Upvotes: 1
Reputation: 25
I think that You can use list> for grouping list of Objects to another list of Objects.
Upvotes: -1