1
votes

Liste Somme des mêmes éléments Plage

J'ai une Liste et je veux additionner les mêmes valeurs

var result = new List<DataPoint>
{
    new DataPoint(){Name = "Test",Value = 30},
    new DataPoint(){Name = "Test1",Value = 20},
    new DataPoint(){Name = "Test",Value = 11}
};

le résultat devrait être une autre liste qui ressemble à ceci (additionner tous les noms "Test", avant un autre nom)

var list = new List<DataPoint>
{
    new DataPoint(){Name = "Test",Value = 10},
    new DataPoint(){Name = "Test",Value = 10},
    new DataPoint(){Name = "Test",Value = 10},
    new DataPoint(){Name = "Test1",Value = 20},
    new DataPoint(){Name = "Test",Value = 11}
};

comment puis-je faire cela?


1 commentaires

L'exemple laisse donc quelques questions sur d'autres cas. Si après l'entrée «Test1», il y a plusieurs entrées «Test», doivent-elles également être additionnées ou s'agit-il simplement du premier ensemble d'entrées «Test»? Et s'il y a plusieurs entrées "Test1"?


5 Réponses :


0
votes

D'abord, vous additionnez les premiers points de données aussi longtemps qu'ils portent le nom "Test". Ensuite, vous créez une nouvelle liste qui contient un nouveau point de données avec votre somme. À cela, vous ajoutez tous les éléments de votre première liste qui viennent après que vos points de données sont appelés test. Vous pouvez utiliser les méthodes LINQ TakeWhile et SkipWhile pour cela.

int sum = list.TakeWhile(x => x.Name == "Test").Sum(x => x.Value);
var firstDataPoint = new DataPoint("Test", sum);
var result = new List<DataPoint> { firstDataPoint };
result.AddRange(list.SkipWhile(x => x.Name == "Test"));


2 commentaires

Cette solution nécessite de mélanger avec la boucle externe s'il y a plus de 2 catégories que je considérerais comme un inconvénient: /


Ceci est lié au commentaire de Knoop à la question. Malheureusement, OP n'a pas spécifié ce qui devrait se passer avec les entrées nommées "Test" qui viennent après un autre nom.



0
votes

Il existe de nombreuses solutions, l'une d'elles est: (mise à jour)

var result = new List<DataPoint>();
var item = list.First();

foreach (var dataPoint in list.Skip(1))
{
    if (item.Name == dataPoint.Name)
    {
        item.Value += dataPoint.Value;
    }
    else
    {
        result.Add(item);
        item = new DataPint() { Name = dataPoint.Name, Value = dataPoint.Value };
    }
}

result.Add(item);

return result.ToList();


2 commentaires

Veuillez vérifier votre solution LINQ . Je pense que cela ne produira pas le résultat attendu pour l'échantillon d'OP.


Cela ne résultera certainement pas en une réponse correcte. Notez que les entrées avec Name = "Test" apparaissent plusieurs fois dans le jeu de résultats (le groupe avant et après l'entrée "Test1" sont des groupes différents)



2
votes

Pourquoi pas une simple boucle? Quelque chose comme ceci:

 result = new List<DataPoint>();

 foreach (DataPoint p in list) 
   if (result.Count <= 0 || result[result.Count - 1].Name != p.Name)
     result.Add(new DataPoint() {Name = p.Name, Value = p.Value});
   else
     result[result.Count - 1].Value += p.Value;


3 commentaires

@Maximilian Ast: Merci! Je suis désolé pour la faute de frappe


Merci beaucoup! Cordialement


J'aime à quel point c'est court tout en atteignant tous les bons points ... très agréable.



0
votes

Je résoudrais ce problème avec une boucle foreach classique et stockerais la valeur précédente dans la somme si le nom est eqal:

var result = new List<DataPoint>();
DataPoint sum = null;

foreach (var dp in list)
{
    if(sum == null)
    {
        // First element, so create the sum object
        sum = new DataPoint { Name = dp.Name, Value = dp.Value };
    }
    else if (sum.Name == dp.Name)
    {
        // Same as the one before, so increment the Value
        sum.Value += dp.Value;
    }
    else
    {
        // Differs from the sone before, so store the sum
        result.Add(sum);

        // Reset the sum
        sum = new DataPoint { Name = dp.Name, Value = dp.Value };
    }
}

// Add the last sum to the group
result.Add(sum);

Résultat: p >

DP: {Test, 30}
DP: {Test1, 20}
DP: {Test, 11}


0 commentaires

0
votes
Name: Test, Value: 30
Name: Test1, Value: 20
Name: Test, Value: 11

0 commentaires