Array Gestaltung fällt schwer



  • Ich habe ein main-Programm, welches eine bestimmte Postleitzahl an ein Unterprogramm übermittelt. Dieses Unterprogramm verglaicht, die Daten und sieht, dass es zwei Datentypen Kd gibt, die die gewünschte PLZ haben und nun möchte ich die an das main Programm zurück übergeben. Mit einer PLZ ist es leicht, man übergibt einfach den aktuellen Wert für Kd:

    public Kunde HoleMirEinigeKunden(string Postleitzahlen)
            {
                foreach (Kunde Kd in liste)
                {
                    if (Postleitzahlen == Kd.Postleitzahl)
                    {
                            return Kd;
                    }
                }
                return null;
    

    Bei mehreren Werten, wir der letzt so immer überschrieben denke ich, also müsste ja ein Array gefertigt werden, aber da fällt mir das Argument, also der Wert nicht ein, über welchen ich arbeiten muss.

    return Kd[];
    

    Was kommt in die Klammer?



  • Oder hat jemand eine Idee, wie ich mehrere Datensätze an die main Funktion zurückgebe? Die Main sieht so aus:

    namespace prg4
    {
        class multipleraiseofcredit
        {
            static void Main(string[] args)
            {
                Kundentabelle kdtab = new Kundentabelle();
                kdtab.LoadFromFile("d:\\xxx\\Kunden.txt");
                Kunde Kd = kdtab.HoleMirEinigeKunden("23456");
                Kd.Kreditlimit = Kd.Kreditlimit + 1;
            }
        }
    }
    

    In Kunde KD sind Ort, PLZ und Kreditlimit hinterlegt und bei den PLZ 23456 soll dann das Kreditlimit um 1 erhöht werden.



  • Probleme die ich sehe:
    - Deine Methode sagt "Kunden" - also die Plural form, aber du returnierst nur einen, das ist dann irreführend.
    - Du hast alles auf Deutsch

    Erstell dir lieber eine Liste und pack alle passenden Kunden dort hinein und returniere diese, besser als ein Array.

    public List<Customer> GetCustomers(string zipCode)
    {
        var affectedCustomers = new List<Customer>();
        foreach (var customer in customers)
        {
            if (zipCpde == customer.ZipCode)
            {
                affectedCustomers.Add(customer);
            }
        }
        return affectedCustomers;
    }
    

    Einfacher ist es mit Linq:

    public IEnumerable<Customer> GetCustomers(string zipCode)
    {
        return customers.Where(c => zipCpde == customer.ZipCode);
    }
    

    Ein tut über Arrays ist hier: http://msdn.microsoft.com/en-us/library/aa288453(v=vs.71).aspx
    Du kannst auch wenn du unbedingt ein array returnieren willst, die Liste auch mit .ToArray() ein ein fertiges Array wandeln.

    Die Liste hat den Vorteil das du die anzahl nicht wissen muss, sie ist dynamisch sodass du beliebig hinzufügen oder entfernen kannst.

    //Dazu
    Erstelle immer Pro Problem ein separaten Thread, zwecks übersicht.



  • Warum meinen eigentlich immer alle, (offensichtlich totalen) Anfängern die fortgeschrittenen Methoden aufzeigen zu müssen? Ist mir jetzt mehrmals aufgefallen.

    Der TE hat ja offenbar noch ein Verständnisproblem generell, trotzdem wird er direkt mit für ihn vermutlich völlig unverständlichem Linq-Code zugebombt. Was soll das nützen, außer, dass es noch mehr verwirrt?

    Das bezieht sich jetzt nicht ausschließlich auf diesen Thread, auch im C++-Forum werden Anfängern bspw. häufig elegante Lösungsmöglichkeiten mit Templates bzw. sogar Template-Metaprogrammierung präsentiert.



  • wurzelkind schrieb:

    Warum meinen eigentlich immer alle, (offensichtlich totalen) Anfängern die fortgeschrittenen Methoden aufzeigen zu müssen? Ist mir jetzt mehrmals aufgefallen.

    Der TE hat ja offenbar noch ein Verständnisproblem generell, trotzdem wird er direkt mit für ihn vermutlich völlig unverständlichem Linq-Code zugebombt. Was soll das nützen, außer, dass es noch mehr verwirrt?

    Das bezieht sich jetzt nicht ausschließlich auf diesen Thread, auch im C++-Forum werden Anfängern bspw. häufig elegante Lösungsmöglichkeiten mit Templates bzw. sogar Template-Metaprogrammierung präsentiert.

    Und deine Alternative Lösung wäre dann welche? Mal davon abgesehen das ich auch deiner Meinung bin, aber dennoch musst du eine Alternativlösung präsentieren wenn du kritisierst 😉



  • @wurzelkind

    Schau mal genauer hin, ich habe 2 Varianten aufgezeigt, eines mit einer List und erst danach eine Linq Variante.
    Auf Linq bin ich auch nicht weiter eingegangen, es war nur um auf zu zeigen wie es einfacher geht, eine Alternative.



  • Ich finde die beiden vorgeschlagenen Lösungen super, solange es nicht bei der verwirrenden bleibt;)

    Habe jetzt die Listen überführung an die main fettig und auch richtig, der Kopf sieht so aus:

    public List<Kunde> HoleMirEinigeKunden(string Postleitzahlen)
    

    Wie muss ich die main nun ändern?

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Daten;
    
    namespace prg4
    {
        class multipleraiseofcredit
        {
            static void Main(string[] args)
            {
                Kundentabelle kdtab = new Kundentabelle();
                kdtab.LoadFromFile("d:\\heinemann\\Kunden.txt");
                Kunde Kd = kdtab.HoleMirEinigeKunden("23456");
                Kd.Kreditlimit = Kd.Kreditlimit + 1;
                kdtab.SaveToFile("d:\\heinemann\\New.txt");
            }
        }
    }
    

    Bei

    Kunde Kd=kdtab.HoleMirEinigeKunden("23456");
    

    erhalte ich eine Fehlermeldung, weil er ja nicht weiß, dass ich eine Liste zurückgegeben habe?



  • Wissen tut der Compiler das schon und er teilt dir auch mit das du nicht in der Lage bist den richtigen Rückgabetyp bereitzustellen 🙂

    Du musst natürlich anstatt:

    Kunde Kd=kdtab.HoleMirEinigeKunden("23456");
    

    folgendes formulieren:

    List<Kunde> kunden =kdtab.HoleMirEinigeKunden("23456");
    


  • Wobei das kunden wohl Kundenliste heißen muss, da mein Kopf der Rückgabe ja so aussieht:

    public List<Kunde> HoleMirEinigeKunden(string Postleitzahlen
    

    Dann meckert er aber in main bei Kd.Kreditlimit da Kd im Kontext nicht vorhanden ist!



  • Ich meine da Kundenliste ja zurückgegebn wird über return:

    public List<Kunde> HoleMirEinigeKunden(string Postleitzahlen)
            {
                List<Kunde> Kundenliste = new List<Kunde>();
    
                foreach (Kunde Kd in liste)
                {
                    if (Postleitzahlen == Kd.Postleitzahl)
                    {
                        Kundenliste.Add(Kd);
                    }
                    return Kundenliste;
                }
                return null;
            }
    


  • Wenn Du eine Liste von mehreren Kunden hast, auf welchen Kunden sollte sich kd.Kreditlimit dann beziehen? Du musst dann schon einen Kunden aus der Liste (z.B. mit kd[i] wobei i < kd.Count sein muss) auswählen.

    BTW: Das return _in_ der for-schleife sorgt dafür, dass in der Liste immer nur (höchstens) ein Kunde enthalten ist.



  • Benutzer_1234 schrieb:

    Wobei das kunden wohl Kundenliste heißen muss, da mein Kopf der Rückgabe ja so aussieht

    Kunden ist ja die Pluralform von Kunde, ob es nun ein Array, eine List, ein Stack oder einfach nur ein IEnumerable ist spielt keine rolle. Also "Kunden" ist schon passend

    Benutzer_1234 schrieb:

    public List<Kunde> HoleMirEinigeKunden(string Postleitzahlen)
    {
        List<Kunde> Kundenliste = new List<Kunde>();
    
        foreach (Kunde Kd in liste)
        {
            if (Postleitzahlen == Kd.Postleitzahl)
            {
                Kundenliste.Add(Kd);
            }
            //return Kundenliste; // Du willst doch alle zutreffenden Kunden und nicht nur den ersten mit der gesuchten Postleitzahl.
        }
        return Kundenliste; // Falls es keinen Kunden gibt mit der Postleitzahl ist die Liste am ende einfach leer
    }
    

    In der Hauptfunktion kannst du dann mit der Liste arbeiten, zb indem du allen ein höheres Kredilimit geben kannst

    var kunden = HoleMirEinigeKunden("12345");
    foreach (var kunde in kunden)
        ++kunde.Kreditlimit;
    

    PS.
    Überarbeite dein Style mal etwas:
    - Du mischst die Groß-/Kleinschreibung unnatürlich: Kundenliste statt kundenListe, foreach (Kunde Kd in liste) Kunde statt kunde, (liste ist wieder klein usw)
    - HoleMirEinigeKunden(string Postleitzahlen) wieso Postleitzahlen? Also plural, ist doch nur eine Postleitzahl
    - Warum ist die Postleitzahl kein integer?
    - Woher kommt "liste"? Generell ein schlechter name da man nicht sagen kann was drin und der sinn ist
    - Kd.Kreditlimit = Kd.Kreditlimit + 1 kannst du kürzen zu Kd.Kreditlimit += 1 oder direkt Kd.Kreditlimit++
    - Kundentabelle kdtab - kdtab ist unschön, zum einen brauchst du in c# nicht so streng kürzen, zum anderen bist du da wieder inkonsistent in der Groß-/Kleinschreibung
    - Alles in Deutsch ist generell sehr unschön



  • Warum ist die Postleitzahl kein integer?

    Postleitzahl meines alten Wohnorts: 04849 🙂



  • Muss ich nicht einfach Kd irgendwie intitialiseren bevor ich das mache, da Kd im main ja garnicht bekannt ist und wenn ja wie?



  • Firefighter schrieb:

    Warum ist die Postleitzahl kein integer?

    Postleitzahl meines alten Wohnorts: 04849 🙂

    Das macht nichts, das ist nur eine frage der Ausgabe.



  • Benutzer_1234 schrieb:

    Muss ich nicht einfach Kd irgendwie intitialiseren bevor ich das mache, da Kd im main ja garnicht bekannt ist und wenn ja wie?

    Hä?

    Du bekommst von der Methode eine Liste von X Kunden, du brauchst dann nur über die Liste der Kunden laufen.
    Du willst immer mir nur einen Kunden arbeiten, aber es gibt X Kunden.



  • OK. Danke euch beiden, habe es gerade mit der ausführlichen Hilfe von David W geschafft.

    Postleitzahl muss string sein, da United Kingdom PLz's z.B. so aufgebaut ist:

    Duxford
    CB2 4RG

    Das muss für den internationalen kaufmännischen Bereich berücksichtigt werden 😉

    Alles in allem, nochmal vielen Dank für dein Bemühen. Großes Kino!



  • David W schrieb:

    Firefighter schrieb:

    Warum ist die Postleitzahl kein integer?

    Postleitzahl meines alten Wohnorts: 04849 🙂

    Das macht nichts, das ist nur eine frage der Ausgabe.

    Ok du würdest also, alle 4 Stelligen Postleitzahlen dann künstlich mit einer 0 erweitern um damit zu arbeiten?

    Edit: Mit letzten Post hat sich das sowieso erledigt 😃



  • David W schrieb:

    Postleitzahl meines alten Wohnorts: 04849 🙂

    Das macht nichts, das ist nur eine frage der Ausgabe.

    Als Verantwortlicher für die Verwaltung der Verzeichnisse der Post innerhalb der Finanzverwaltung NRW muss ich hier mal widersprechen. In der Praxis kommt es weit häufiger vor, dass man eine Postleitzahl ausgibt oder aufgrund eines Musters vergleicht, als dass man mit ihr rechnet. Moment, genaugenommen kommt letzterer Fall nie vor.


  • Administrator

    LordJaxom schrieb:

    David W schrieb:

    Postleitzahl meines alten Wohnorts: 04849 🙂

    Das macht nichts, das ist nur eine frage der Ausgabe.

    Als Verantwortlicher für die Verwaltung der Verzeichnisse der Post innerhalb der Finanzverwaltung NRW muss ich hier mal widersprechen. In der Praxis kommt es weit häufiger vor, dass man eine Postleitzahl ausgibt oder aufgrund eines Musters vergleicht, als dass man mit ihr rechnet. Moment, genaugenommen kommt letzterer Fall nie vor.

    Zum Teil haben Postleitzahlen Buchstaben drin. In Deutschland sind mir zwei offizielle bei der Feldpost bekannt: 6490a und 6490b. Die sind aber, glaube ich, nicht mehr in Verwendung. War für die EURO Mission im Kongo. In anderen Länder ist es allerdings, wie schon gesagt wurde, ganz normal, dass Buchstaben darin vorkommen.

    Was man zudem noch oft sieht, sind Länderkürzel vor der eigentlichen Postleitzahl. Zum Beispiel CH6060 für eine Postleitzahl in der Schweiz. Das ist aber, glaube ich, nicht standardkonform.

    Es ist völlig verkehrt für etwas einen Zahlentyp zu nehmen, nur weil es eine Zahl ist. Man nimmt nur eine Zahl, wenn man damit rechnen möchte. Sonst ist es ganz eindeutig eine Zeichenkette und mehr nicht.

    Zum Beispiel mit der 0:
    Die 0 hat nichts mit Ausgabe zu tun! Die Postleitzahl lautet 04849. 4849 ist etwas anderes und somit falsch. Das ist wie auch bei den Telefonnummern. Auch dort dürfen führende Nullen nicht einfach entfernt werden. Das hat nichts mit Ausgabe zu tun.
    Auch wenn ich Vergleiche nicht gerne habe, aber das ist wie, wenn man sagen würde, dass du nur W heisst. Das David ist nur Teil der formatierten Ausgabe.

    Grüssli


Anmelden zum Antworten