Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Zahlen aufsummieren nach Keyword
Automatinator
myCSharp.de - Member



Dabei seit:
Beiträge: 18
Herkunft: C#-Programmierlevel: Anfänger

Themenstarter:

Zahlen aufsummieren nach Keyword

beantworten | zitieren | melden

Hallo myCsharp.de Forum


Ich hab eine spalten-orientierte text-Datei (*.SDC) (spalten=komma-textsymbol)

Ich möchte nun aus dieser Datei nach Key-wörtern in der ersten spalte suchen und immer die Werte des gleichen Keywords auf der gleichen Zeile spalten-seperat aufsummieren.

Beispiel:
Textdatei:
Hund, 1, 2, 3
Katze, 1, 2, 3
Hund, 2, 3, 4

Programmcode-Resultat:
In Tabellenform in DataGridView
Hund | 3 | 5 | 7
Katze | 1 | 2 | 3

Randbedingungen:
Es kann sich hier um ca.:
- 200 Schlüsselwörter
- 4 Spalten
- 1000 Zeilen
handeln

Meine Frage nun:
Kann ich das auch ohne Datenbank lösen? (Ein kollege der ein wenig C# kennt hat gemeint ja)
Wenn ja, wie?
Es gibt ja die Anweisung "new List<Klasse>". Wäre diese der richtige Ansatz?
und über get und set summiere ich die Werte aus der "klasse" auf?

Gibt es noch was besseres als Liste dafür? Oder doch zwingend eine Datenbank?
Vor und nachteile?


Viele Dank schonmal im Vorraus!
Gruss
Automatinator
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Automatinator am .
private Nachricht | Beiträge des Benutzers
Jamikus
myCSharp.de - Member



Dabei seit:
Beiträge: 251
Herkunft: Oberhausen (NRW)

beantworten | zitieren | melden

Eine Datenbank wäre für mich eine Option, wenn man die Daten in der Ursprungsform für zukünftige Prozesse benötigt.

Mit den hier vorliegenden Informationen würde mir eine Liste von Objekte reichen, welches an Hand des Beispiels die Tiere katalogiert und neben Namen mehrere Eigenschaften für Anzahl o.ä. (je nachdem für was die Zahlen stehen) besitzt.

Die Text-Datei zeilenweise lesen, sollte für sich kein Beinbruch sein, weil es dazu etliche Tutorials existieren.

Summieren innerhalb der Eigenschaft wäre sehr unpraktisch bzw. dann wäre die Eigenschaft nicht mehr ordentlich setzbar. Also man könnte z.B. den Wert der Eigenschaft nicht ohne unnötig aufblähen resetten/verringern.
Nebenbei wüßte einzig der Entwickler alleine, wie sich die Eigenschaft verhält, wenn nicht direkt im Namen der Eigenschaft bzw. im Kommentar ersichtlich ist, dass sie sich selbst summiert. Also auch fehleranfällig in der Verwendung.
Aber wenn man will, wäre es möglich. Nur empfehlen würde ich es allemal nicht
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Jamikus am .
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1892
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

Klingt im einfachsten Fall nach einem Ansatz für ein Dictionary.
Dann sind deine Schlüsselwörter die Keys und als Value eine Liste mit den Einträge aus der jeweiligen Zeile.
Hier würde ich pro Zeile ein Objekt mit allen Spalten anlegen und dann die Datei einmal einlesen und ber das Schlüsselwort einen Eintag anlegen.

Auf eine Datenbank würde ich setzen, wenn die Daten später noch weiterverarbeitet oder andersweite benötigt werden.
Für einen einzelnen Durchlauf, würde ich noch nicht auf eine Datenbank zugreifen.

Nachtrag:
Wenn du nur die summierten Werte braucht, kannst du anstelle einer Liste auch einen Eintrag mit den entsprechenden Eigenschaften als Value im Dictionary anlegen.
Dann musst du nur beim durchlaufen der Zeilen, die entsprechenden Eigenschaften summieren.
Somit kannst du dann direkt die Daten im GridView aus den Values binden.

T-Virus
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von T-Virus am .
Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
private Nachricht | Beiträge des Benutzers
Automatinator
myCSharp.de - Member



Dabei seit:
Beiträge: 18
Herkunft: C#-Programmierlevel: Anfänger

Themenstarter:

beantworten | zitieren | melden

Zitat von T-Virus
Klingt im einfachsten Fall nach einem Ansatz für ein Dictionary.
... ...
Wenn du nur die summierten Werte braucht, kannst du anstelle einer Liste auch einen Eintrag mit den entsprechenden Eigenschaften als Value im Dictionary anlegen.
Dann musst du nur beim durchlaufen der Zeilen, die entsprechenden Eigenschaften summieren.
Somit kannst du dann direkt die Daten im GridView aus den Values binden.

Danke für die rasche Antwort!

Was meinst Du mit Dictionary? new List<>?

Es ist nicht ganz so einfach
Eigentlich ist wie folgt aufgebaut:

Suchwort=Gruppenwort-Indikator, Wert1, Wert2, Wert3

Beispiel:
Animal=Hund, 1, 2, 3
Animal=Katze, , 1, 2
Animal=Hund, , 3, 4
BlaBla
Human=Tim, , , 1
Human=Tim, 1, 2, 3
Human=Peter, 4, 5, 5
Bla bla
bla bla

Legende:
'Blabla'
Text, welcher ignoriert wird
'Animal='
Dem Programm bekanntes Keyword für Gruppentyp und relevante Daten in dieser Zeile
'Hund' 
Dem Programm vorerst unbekanntes Gruppenwort, welche die auf Werte in der gleiche Zeile aufsummieren (wie im ersten Startbeitrag erklärt und beispielhaft gezeigt)
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Automatinator am .
private Nachricht | Beiträge des Benutzers
Automatinator
myCSharp.de - Member



Dabei seit:
Beiträge: 18
Herkunft: C#-Programmierlevel: Anfänger

Themenstarter:

beantworten | zitieren | melden

Zitat von Jamikus

Die Text-Datei zeilenweise lesen, sollte für sich kein Beinbruch sein, weil es dazu etliche Tutorials existieren.

Summieren innerhalb der Eigenschaft wäre sehr unpraktisch bzw. dann wäre die Eigenschaft nicht mehr ordentlich setzbar. Also man könnte z.B. den Wert der Eigenschaft nicht ohne unnötig aufblähen resetten/verringern.
Nebenbei wüßte einzig der Entwickler alleine, wie sich die Eigenschaft verhält, wenn nicht direkt im Namen der Eigenschaft bzw. im Kommentar ersichtlich ist, dass sie sich selbst summiert. Also auch fehleranfällig in der Verwendung.
Aber wenn man will, wäre es möglich. Nur empfehlen würde ich es allemal nicht

Datei einlesen nicht, aber das aufsummieren der Daten.

Ergibt es sinn, wenn ich eine selbst generierte Text-Datei, als Datenbank verwende?
Was ist mit dieser DataTable Klasse? würde das mit dieser Funktionieren?
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Automatinator am .
private Nachricht | Beiträge des Benutzers
trib
myCSharp.de - Member



Dabei seit:
Beiträge: 691

beantworten | zitieren | melden

Sofern ich Dein gewünschtes Ergebnis korrekt verstehe, hast Du zwei Aufgaben.
  1. Gruppieren der Daten
  2. Implementierung einer Suche


Wenn Du nun den Text in ein Dictionary einliest, darfst Du nur einen Eintrag pro Tier/Keyword haben.
Gibt es diesen noch nicht, legst Du ihn an. Existiert das Keyword bereits, addierst Du die Werte auf.

Dann kannst Du das Dictionary darstellen. Ob direkt an ein DGV gebunden oder mit dem Umweg der DataTable.
Letzteres ermöglicht Dir eine recht einfache Filterung im DataGridView. Ohne zu wissen was dann damit passiert, kann ich keine Empfehlung dazu aussprechen.
Es gibt etliche Möglichkeiten für die Suche/Filterung.
private Nachricht | Beiträge des Benutzers
Caveman
myCSharp.de - Member

Avatar #avatar-3854.jpg


Dabei seit:
Beiträge: 140

beantworten | zitieren | melden

Die Aufgabenstellung hat mich interessiert ;)

using System;
using System.Collections.Generic;

namespace MyCSharp122687
{
    class Program
    {
        private static List<string> text = new List<string>();
        private static Dictionary<string, List<int>> groups = new Dictionary<string, List<int>>();

        static void Main(string[] args)
        {
            text.Add("Hund, 1, 2, 3");
            text.Add("Katze, 1, 2, 3");
            text.Add("Hund, 2, 3, 4");

            foreach (string entry in text)
            {
                string[] textblocks = entry.Split(',');
                string[] trimmedTextBlocks = TrimTextBlocks(textblocks);
                if (groups.ContainsKey(trimmedTextBlocks[0]))
                {
                    AddValues(trimmedTextBlocks);
                }
                else
                {
                    List<int> numbers = new List<int>();
                    for (int i = 0; i < textblocks.Length - 1; i++)
                    {
                        numbers.Add(0);
                    }
                    groups.Add(trimmedTextBlocks[0], numbers);

                    AddValues(trimmedTextBlocks);
                }
            }

            //Output
            foreach (KeyValuePair<string, List<int>> group in groups)
            {
                Console.Write(group.Key);
                foreach (int number in group.Value)
                {
                    Console.Write(" | ");
                    Console.Write(number);
                }
                Console.WriteLine();
            }
            Console.ReadKey();
        }

        /// <summary>
        /// Add values to dictionary
        /// </summary>
        /// <param name="textblocks">The splitted representation of a record in the input file</param>
        private static void AddValues(string[] textblocks)
        {
            List<int> numbers = groups[textblocks[0]];
            for (int i = 1; i < textblocks.Length; i++)
            {
                if (int.TryParse(textblocks[i], out int number))
                {
                    numbers[i - 1] += number;
                }
                else
                {
                    throw new ArgumentException();
                }
            }
        }

        /// <summary>
        /// Remove all leading and trailing whitespaces
        /// </summary>
        /// <param name="textblocks">The splitted representation of a record in the input file</param>
        /// <returns>The trimmed text blocks</returns>
        private static string[] TrimTextBlocks(string[] textblocks)
        {
            string[] returnValue = new string[textblocks.Length];
            for (int i = 0; i < textblocks.Length; i++)
            {
                returnValue[i] = textblocks[i].Trim();
            }
            return returnValue;
        }
    }
}
private Nachricht | Beiträge des Benutzers
Automatinator
myCSharp.de - Member



Dabei seit:
Beiträge: 18
Herkunft: C#-Programmierlevel: Anfänger

Themenstarter:

beantworten | zitieren | melden

Zitat von trib
Sofern ich Dein gewünschtes Ergebnis korrekt verstehe, hast Du zwei Aufgaben.
  1. Gruppieren der Daten
  2. Implementierung einer Suche


Wenn Du nun den Text in ein Dictionary einliest, darfst Du nur einen Eintrag pro Tier/Keyword haben.
Gibt es diesen noch nicht, legst Du ihn an. Existiert das Keyword bereits, addierst Du die Werte auf.

Dann kannst Du das Dictionary darstellen. Ob direkt an ein DGV gebunden oder mit dem Umweg der DataTable.
Letzteres ermöglicht Dir eine recht einfache Filterung im DataGridView. Ohne zu wissen was dann damit passiert, kann ich keine Empfehlung dazu aussprechen.
Es gibt etliche Möglichkeiten für die Suche/Filterung.

Ich habe eine Textdatei wie folgt:
Beispiel:

Animal=Hund, 1, 2, 3
Animal=Katze, , 1, 2
Animal=Hund, , 3, 4
BlaBla
Human=Tim, , , 1
Human=Tim, 1, 2, 3
Human=Peter, 4, 5, 5
Bla bla
bla bla

Legende:
'Blabla'

Text, welcher ignoriert wird
'Animal='

Dem Programm bekanntes Keyword für Gruppentyp und relevante Daten in dieser Zeile
'Hund'

Dem Programm vorerst unbekanntes Gruppenwort, welche die auf Werte in der gleiche Zeile aufsummieren (wie im ersten Startbeitrag erklärt und beispielhaft gezeigt)

Aufgabe des Tools/Codes:
Aus dieser Textdatei muss ich die Werte spalten-seperat aufsummieren nach "Gruppenwort" (Hund,Katze,Tim,Peter), welche noch unbekannt sind, aber gefunden werden durch die bekannten vordefinierten "Keywords".

Anzeige:
Diese Tabelarisch Gruppenweise zusammen gefasst (aufsummierte Werte) (z.b. in DataGridView oder als Import für Excel)


Frage:
Geht das mit dem Dictionary auch, mit mehreren werten pro Keyword?
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1892
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

@Automatinator
Die Frage kann man, wie bereits geschehen, mit ja beantworten.
Und wie du es machen kannst, habe ich auch oben beschrieben.
Du musst auch selbst aktiv werden und Code schreiben.
In den mehr als 7 Stunden, die du auf eine Antwort gewartest hast, hättest du auch mit etwas lesen in der Doku und testen, das Problem lösen können.
Den Ansatz dafür hast du bereits.

Anbei solltest du dann aber, weil du es anfangs nicht erwähnt hast, den gesamten Text als Key im Dictionary verwenden.
Also "Animal=Hund" sollte auch der Key im Dictionary sein.
Wenn jemand mal z.B. "Human=Hund" einträgt, würdest du diese falsch summieren, da du dann unterschiedliche Gruppen mit selber Bezeichnung vermischen würdest.

Ansonsten solltest du dringend in die Doku schauen, wenn du nicht weißt was du tun sollst.

Doku

T-Virus
Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
private Nachricht | Beiträge des Benutzers