如何通过一些属性将List <object>分组到另一个List <object>

时间:2019-04-28 18:05:23

标签: java android kotlin

我正在尝试对包含

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

3 个答案:

答案 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作为生成地图的键,对emailAddressPair进行分组:

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>将对象列表分组为另​​一个对象列表。