Laden...

Zahlen aufsummieren nach Keyword

Erstellt von Automatinator vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.869 Views
A
Automatinator Themenstarter:in
18 Beiträge seit 2020
vor 4 Jahren
Zahlen aufsummieren nach Keyword

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

J
251 Beiträge seit 2012
vor 4 Jahren

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

T
2.219 Beiträge seit 2008
vor 4 Jahren

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

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.

A
Automatinator Themenstarter:in
18 Beiträge seit 2020
vor 4 Jahren

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)

A
Automatinator Themenstarter:in
18 Beiträge seit 2020
vor 4 Jahren

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.

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?

T
708 Beiträge seit 2008
vor 4 Jahren

Sofern ich Dein gewünschtes Ergebnis korrekt verstehe, hast Du zwei Aufgaben.
1.Gruppieren der Daten 1.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.

187 Beiträge seit 2009
vor 4 Jahren

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;
        }
    }
}
A
Automatinator Themenstarter:in
18 Beiträge seit 2020
vor 4 Jahren

Sofern ich Dein gewünschtes Ergebnis korrekt verstehe, hast Du zwei Aufgaben.
1.Gruppieren der Daten 1.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?

T
2.219 Beiträge seit 2008
vor 4 Jahren

@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.