2016-07-31 12 views
0

Ich arbeite an einer Spesen-Tracking-Anwendung, wo ein Benutzer Informationen eingibt und einige Analysen am Back-End durchgeführt werden. Jeder Ausgabeneintrag hat vier Elemente - Datum, Kategorie, Betrag, Kommentar. Diese werden in eine Kategorieliste eingespeist, deren Einträge einen Namen, eine Summe und einen Prozentsatz haben. Wenn jetzt ein neuer Eintrag in der Ausgabenliste gemacht wird, löst dies ein Ereignis aus, das prüft, ob der Kategoriename existiert. Wenn dies der Fall ist, wird der Betrag zur Gesamtsumme der Kategorie hinzugefügt. Ist dies nicht der Fall, wird der Kategorieliste ein neuer Eintrag hinzugefügt. Die Summe aller Kategoriensummen wird auch als separate Variable beibehalten.Aktualisierungskategorie Prozentsätze in C# -Liste

Um aktualisierte Prozentsätze pro Kategorie zu haben, habe ich am Ende des Ereignisses eine for-Schleife, die jedes Element in der Liste durchläuft. Es nimmt die Kategorie total und teilt sie durch die Summe aller Summen auf, bevor es mit 100 multipliziert wird. Das macht den Job erledigt, aber scheint mir schlampig zu sein, wenn zu viel Arbeit an jedem Eintrag gemacht wird. Kann jemand einen effizienteren Weg empfehlen, dies zu tun? Ich füge den Ereigniscode unten ein, kann aber bei Bedarf weitere Informationen bereitstellen.

public void SelectedExpenseEntry_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) 
{ 
     ExpenseEntry dummyEntry = (ExpenseEntry)sender; 

     if ((dummyEntry.ExpenseDate != "MM/DD/YYYY") && (dummyEntry.ExpenseCategory != "Category") && (dummyEntry.ExpenseAmount != 0) && (dummyEntry.ExpenseComment != "Comment")) 
     { 
      CategoryEntry TemperCategory = new CategoryEntry(); 
      ExpenseEntry TempExpenseEntry = new ExpenseEntry(); 
      TempExpenseEntry = dummyEntry; 
      TemperCategory.CategoryName = TempExpenseEntry.ExpenseCategory; 
      TemperCategory.CategoryTotal = TempExpenseEntry.ExpenseAmount; 
      TemperCategory.CategoryPercent = 0; 

      ListTotal = ListTotal + TempExpenseEntry.ExpenseAmount; 

      int index = SingleMonthsCategories.IndexOf(SingleMonthsCategories.Where(x => x.CategoryName == TemperCategory.CategoryName).FirstOrDefault()); 
      if(index == -1) 
      { 
       SingleMonthsCategories.Add(TemperCategory); 
      } 
      else 
      { 
       SingleMonthsCategories[index].CategoryTotal = SingleMonthsCategories[index].CategoryTotal + TemperCategory.CategoryTotal; 
      } 

      for (int i = 0; i < SingleMonthsCategories.Count; i++) 
      { 
       SingleMonthsCategories[i].CategoryPercent = (SingleMonthsCategories[i].CategoryTotal/ListTotal) * 100; 
      }; 

     } 
} 

Vielen Dank im Voraus,

Yusif Nurizade

+0

Rechnen Sie die Prozentsätze jedes Mal neu, wenn Sie sie anzeigen? Sie sollten überlegen, sie in einem Wörterbuch zwischenzuspeichern, wenn dies der Fall ist. –

+0

"Vorzeitige Optimierung ist die Wurzel allen Übels" - Donald Knuth –

Antwort

0

Das Problem weggehen könnte, wenn Sie nicht CategoryPercent eine Eigenschaft von CategoryEntry machen. Wenn eine CategoryEntry eine Eigenschaft hat, die angibt, wie viel Prozent der Summe es darstellt, dann "weiß" sie gewissermaßen über die anderen Kategorien.

Es wird noch verwirrender, wenn eine Person CategoryEntry jemals zu mehr als einer Sammlung gehören musste. Dann, welche Sammlung würde sich auf CategoryPercent beziehen? CategoryPercent ist wirklich eine Funktion von CategoryEntryund eine Liste von Kategorien.

Da es sich um einen berechneten Wert handelt - Benutzer geben Beträge und nicht den Prozentsatz der Gesamtsumme ein - ist es sinnvoller, sie nur zu berechnen, wenn Sie sie benötigen.

Wenn SingleMonthCategories ein List<CategoryEntry> (nur Raten) ist, dann könnten Sie eine Klasse dafür erstellen und eine Methode hinzufügen, die die Summe für alle Kategorien zurückgibt. Sie können auch eine Funktion erstellen, die den Prozentsatz der Gesamtsumme für einen bestimmten Eintrag zurückgibt.

public class CategoryEntries : List<CategoryEntry> 
{ 
    public decimal TotalExpense() 
    { 
     return this.Select(category => category.ExpenseAmount).Sum(); 
    } 

    public decimal PercentOfTotal(CategoryEntry entry) 
    { 
     return entry.TotalExpense/TotalExpense(); 
    } 
} 

Dieser Ansatz kann ineffizient werden, wenn Sie Tausende von Einträgen in einer Liste haben. Anderenfalls wird die Berechnung der Gesamtsumme schnell erfolgen. Und wenn Sie mehrere Prozentsätze auf einmal berechnen müssen, können Sie immer TotalExpense() einmal anrufen und dann alle einzelnen Kategorien durch diesen einen Betrag teilen.