1
votes

Flatten Map > sur List (conversion CSV) avec des flux

Entrée donnée (clé de mappage: valeur)

"a,c"
"a,d"
"a,e"
"b,c"

Sortie triée souhaitée:

"a":["e","c","d"]
"b":["c"]


9 commentaires

Google "comment utiliser flatMap avec java stream"


Cela pourrait vraiment être aussi simple que: map.forEach ((k, v) -> v.forEach (val -> list.add (k + "," + val))) . Essayez-le une fois!


@Naman c'est une mauvaise solution, ce n'est pas très fonctionnel


@hey_you bien, qu'est-ce qui n'est pas fonctionnel? pourriez-vous expliquer mauvais ici en termes de quoi?


@Naman le fait que vous utilisez foreach partout, pourrait aussi bien écrire un normal pour à la place.


@hey_you Le simple fait de les utiliser partout ne les rend pas mauvais, je dirais. Quoi qu'il en soit, je ne mute aucun objet itéré ni ne produit aucun autre effet secondaire. J'espère donc vraiment que la boucle for peut être représentée comme le forEach en toute sécurité dans ce cas.


@hey_you simple flatMap n'est probablement pas suffisant, je ne veux pas simplement aplatir toutes les valeurs, mais comme décrit ci-dessus.


La modification aggrave la question. Pourquoi voudriez-vous représenter les nombres sous forme de chaînes et ensuite avoir besoin qu'ils soient triés par valeurs numériques?


@Naman vous avez un point, je modifie encore une fois pour éviter toute confusion sur les règles de tri


3 Réponses :


1
votes

Ce que vous pourriez éventuellement rechercher, c'est d'utiliser flatMap avec une sorte de valeurs modifiées pour comparer les valeurs entières converties comme:

return map.entrySet().stream()
        .flatMap(e -> e.getValue().stream()
                .sorted(Comparator.comparingInt(Integer::parseInt)) // or just .sorted()
                .map(v -> e.getKey() + "," + v))
        .collect(Collectors.toList());


0 commentaires

0
votes

Je ne sais pas si c'est une solution parfaite, mais cela fonctionne.

map.entrySet().stream()
  .map(entry.getValue().stream()
     .sorted()
     .map(value->entry.getKey()+","+value)
     .collect(Collectors.joining("\n"))
  )
  .sorted()
  .collect(Collectors.joining("\n"));


0 commentaires

1
votes

Pour que cela reste lisible, il est préférable de diviser le code en deux méthodes, afin de ne pas intégrer la logique flatMap :

public List<String> toPairs(Map<String, Set<String> map) {
    return map.entrySet().stream()
        .flatMap(this::entryPairs)
        .sorted() // if you want the whole output to be sorted
        .collect(Collectors.toList())
}

private Stream<String> entryPairs(Map.Entry<String, Set<String>> entry) {
    return entry.getValue().stream()
        // .sorted() // you can sort the values for each key here, but this is useless if you're sorting above
        .map(v -> entry.getKey() + ',' + v)
}


0 commentaires