8
votes

Y a-t-il un meilleur moyen d'agréger un dictionnaire à l'aide de Linq?

J'essaie de construire un dictionnaire d'une énorme, mais j'ai besoin d'un agrégateur pour toutes les clés potentiellement dupliquées. L'utilisation de Todimicatrice () a directement causé parfois des touches en double.

Dans ce cas, j'ai un tas d'entrées de temps ({DateTime Date, Double heures}), et si plusieurs entrées de temps se produisent le même jour, je veux le total Temps pour ce jour. I.e., un agrégateur personnalisé, qui me donnera une clé unique pour une entrée de dictionnaire. P>

Y a-t-il une meilleure façon de le faire que cela? p>

(cela fonctionne.) P>

    public static Dictionary<TKey, TValue> ToDictionary<T, TKey, TValue>(
        this IEnumerable<T> input, 
        Func<T, TKey> keySelector, 
        Func<T, TValue> valueSelector, 
        Func<IEnumerable<TValue>, TValue> duplicateResolver)
    {
        return input
            .GroupBy(keySelector)
            .Select(group => new { group.Key, Value = duplicateResolver(group.Select(valueSelector)) })
            .ToDictionary(k => k.Key, k => k.Value);
    }


2 commentaires

Voulez-vous dire que vous souhaitez purifier la clé ou voulez-vous supprimer les DUPS?


J'ai mis à jour la description. Essayer d'agréger les doublons pour les rendre uniques, puis construire un dictionnaire de cela.


5 Réponses :


3
votes

Si les clés en double sont un problème, vous voulez peut-être dire TolOookUp ? Même principal, mais plusieurs valeurs par clé ... xxx

alors vous faites simplement quelque chose comme: xxx

ou utilisez SELECTMANY bien sûr ( de ... de ).


0 commentaires

0
votes

Si vous accédez à l'indexeur d'un dictionnaire et il n'y a rien là-bas, il vous permet de définir qu'il renvoie une construction par défaut du type de données, dans le cas d'un double ce sera 0. Je ferais peut-être quelque chose comme

public void blabla(List<TimeEntry> hoho)
{
    Dictionary<DateTime, double> timeEntries = new Dictionary<DateTime, double>();
    hoho.ForEach((timeEntry) =>
        {
            timeEntries[timeEntry.Day] = 0;
        });

    hoho.ForEach((timeEntry) =>
        {
            timeEntries[timeEntry.Day] += timeEntry.Hours;
        });

}


1 commentaires

Génère KeyNotFoundException: la clé donnée n'était pas présente dans le dictionnaire sur le TIMENTRIES [] + = appel. Vous devez initialiser la valeur du dictionnaire avant de pouvoir utiliser + = dessus.



1
votes

J'aime votre méthode parce que c'est clair, mais vous voulez le rendre plus efficace, vous pouvez effectuer ce qui suit qui effectuera toutes les agrégations et regrouper dans un seul appel code> appel code>, mais un.

private static Dictionary<DateTime, double> CreateAggregatedDictionaryByDate(IEnumerable<TimeEntry> timeEntries)
{
    return timeEntries.Aggregate(new Dictionary<DateTime, double>(),
                                 (accumulator, entry) =>
                                    {
                                        double value;
                                        accumulator.TryGetValue(entry.Date, out value);
                                        accumulator[entry.Date] = value + entry.Hours;
                                        return accumulator;
                                    });
}


1 commentaires

Agréable. Un peu compliqué ... mais oui. Je suppose que je ne suis pas vraiment sûr de ce que je cherche. Peut-être une surcharge pour Todimicatrice () qui fournit un troisième paramètre pour résoudre des doublons?



0
votes

cherchez-vous quelque chose comme ça? XXX


2 commentaires

Ouais, c'est exactement ce que j'ai, juste avec la syntaxe de la méthode de l'extension.


Le mien est différent en ce qu'il met l'agrégat dans l'appel plutôt que de l'informer en premier.



6
votes
Dictionary<DateTime, double> result = timeEntries.ToDictionary(
  te => te.Date,
  te => te.Hours,
  g => g.Sum()
);

0 commentaires