¿Cómo dividir una matriz de objetos en una submatriz en función de múltiples valores de propiedad/campo?

Resuelto Software Developer asked hace 10 meses • 0 respuestas

Tengo una lista de objetos. Aquí están las propiedades del objeto (son una jerarquía):

Identificación/nombre del distrito escolar

Identificación/nombre de la escuela

ID/nombre de grado

ID/nombre del sujeto

Identificación/nombre del estudiante

He ordenado esta lista por distrito escolar, luego escuela, luego grado y luego por materia. Básicamente, todos los elementos de la lista que tengan exactamente el mismo distrito escolar, escuela, grado y materia estarán uno al lado del otro en la lista.

Pero, ¿cómo puedo dividir la lista en sublistas según esta condición? Cada sublista tendría que ser objetos con el mismo distrito escolar, escuela, grado y materia. No quiero un mapa ni ninguna otra estructura de datos; quiero una lista de listas/sublistas.

Gracias.

Software Developer avatar Feb 17 '24 02:02 Software Developer
Aceptado

dado que las estructuras de datos:

record ElementKey(String district, String school, String grade) {
    public ElementKey(Element element) {
        this(element.district(), element.school(), element.grade());
    }
}

record Element(String district, String school, String grade, String subject, String student) {
}

aquí estamos:

/**
 * Assuming list is sorted by key
 *
 * @param elements list of elements to group
 * @return lists of elements grouped by key
 */
private static List<List<Element>> subList1(List<Element> elements) {
    if (elements == null || elements.isEmpty()) {
        return List.of();
    }
    List<List<Element>> listOfList = new ArrayList<>();
    listOfList.add(new ArrayList<>());
    ElementKey latestKey = new ElementKey(elements.get(0));
    for (Element element : elements) {
        ElementKey currentKey = new ElementKey(element);
        if (!currentKey.equals(latestKey)) {
            listOfList.add(new ArrayList<>());
            latestKey = currentKey;
        }
        listOfList.get(listOfList.size() - 1).add(element);
    }
    return listOfList;
}

o, mucho mejor, y no es necesario ordenar la lista de fuentes

private static List<List<Element>> subList(List<Element> elements) {
    return elements.stream()
            .collect(Collectors.groupingBy(ElementKey::new, Collectors.toList()))
            .values().stream()
            .toList();
}

No sé si entendí correctamente la estructura de datos, pero al final lo que cuenta es el concepto:

  1. iterar sobre la colección
  2. mantener el seguimiento del último elemento
  3. cuando cambia: crea otra sublista

Tomando el término "sublista" literalmente, si desea una sublista sin copias en lugar de nuevas listas de matrices, aquí está la cosa:

private static List<List<Element>> realSubList(List<Element> elements) {
    if (elements == null || elements.isEmpty()) {
        return List.of();
    }
    List<List<Element>> listOfList = new ArrayList<>();
    int fromIndex = 0;
    for (int i = 0; i < elements.size(); i++) {
        if (!isSameGroup(elements.get(fromIndex), elements.get(i))) {
            listOfList.add(elements.subList(fromIndex, i));
            fromIndex = i;
        }
    }
    listOfList.add(elements.subList(fromIndex, elements.size()));
    return listOfList;
}
Stefano Riffaldi avatar Feb 16 '2024 20:02 Stefano Riffaldi