Laden...

Ordnungszahlen für eingefügte Elemente ermitteln

Erstellt von jaensen vor 11 Jahren Letzter Beitrag vor 11 Jahren 2.973 Views
jaensen Themenstarter:in
2.760 Beiträge seit 2006
vor 11 Jahren
Ordnungszahlen für eingefügte Elemente ermitteln

Beschreibung:

In manchen Anwendungen werden Elemente anhand einer Ordnungszahl verwaltet. Wenn man nun nachträglich irgendwo mittendrin eine Zeile einfügen möchte so muss man auch eine Ordnungszahl angeben die zwischen der vorhergehenden und nachfolgenden liegt. Das kann dieses Snippet übernehmen.

Anwendungsfälle finden sich z.B. in EDI-Formaten oder älteren ERP-Systemen.


        /// <summary>
        /// Takes a list of integers and inserts numbers where nessecary (where the value is 0).
        /// </summary>
        /// <param name="numbersList">The list</param>
        /// <param name="defaultIncrement">The default increment value</param>
        /// <example>
        /// If we have the following list and the defaultIncrement is 10000
        /// 
        /// LineNo.:
        /// [00] = 0
        /// [01] = 0
        /// [02] = 10000
        /// [03] = 20000
        /// [04] = 30000
        /// [05] = 0
        /// [06] = 40000
        /// [07] = 50000
        /// [08] = 0
        /// [09] = 60000
        /// [10] = 0
        /// [11] = 0
        /// 
        /// the resulting list would look like this:
        /// 
        /// LineNo.:
        /// [00] = 3333
        /// [01] = 6666
        /// [02] = 10000
        /// [03] = 20000
        /// [04] = 30000
        /// [05] = 35000
        /// [06] = 40000
        /// [07] = 50000
        /// [08] = 55000
        /// [09] = 60000
        /// [10] = 70000
        /// [11] = 80000
        /// </example>
        public static void InsertNumbersBetween(List<int> numbersList, int defaultIncrement) {
            int previousNo = 0;

            for (int i = 0; i < numbersList.Count; i++) {

                int gap = 0;
                int maxLineNo = 0;
                int itemNo = i;

                if (numbersList[i] == 0) {
                    while (itemNo < numbersList.Count &&
                          numbersList[itemNo] == 0) {
                        gap++;
                        itemNo++;
                    }

                    bool endOfList = false;
                    if (itemNo == numbersList.Count) {
                        maxLineNo = previousNo + (gap * defaultIncrement);
                        endOfList = true;
                    } else
                        maxLineNo = numbersList[itemNo];

                    int range = maxLineNo - previousNo;
                    int step = range / (endOfList ? gap : gap + 1);

                    int currentGapElement = 1;
                    for (int y = i; y < i + gap; y++) {
                        numbersList[y] = previousNo + step * currentGapElement;
                        currentGapElement++;
                    }
                } else {
                    previousNo = numbersList[i];
                }
            }
        }
    }


Schlagwörter: Ordnungszahl, Zeilennummer, Einfügen

49.485 Beiträge seit 2005
vor 11 Jahren

Hallo jaensen,

das erinnert mich an die guten alten Basis-Zeiten als jede Zeile noch mit einer Zeilenummer begonnen hat und man später eingefügte Zeilen nach so einem Prinzip nummeriert hat.

Hier noch ein paar kleine Verbesserungsvorschläge:
*Da step ein Integer ist, summieren sich Rundungsfehler bei dessen Berechnungen, je länger die zu füllenden Lücke ist, zu immer größeren Abweichungen. Besser ist es, erst bei der Brechung des jeweils exakten zu füllenden Wert zu runden.

*Dann könntest du auch überlegen, auf das jeweils größere möglichste Raster zu runden, z.B. 5 oder 10 oder 100, was immer gerade möglich ist. So vermeidet man Zeilennummern wie 3333 und 6666, sondern würde da für den menschlichen Leser komfortabler vielleicht besser 3000 und 7000 verwenden. Das Raster darf man natürlich nicht so groß machen, dass zwei Zeilennummern auf den gleichen Wert gerundet werden.

*Wenn gap größer ist als range, könnte und sollte die Methode einen Fehler werfen. Denn in dem Fall sind doppelte Zeilennummern auch bei einem Raster von 1 nicht mehr zu vermeiden.

*Außerdem sollte man überlegen, ob nicht eine Exception geworfen wird, wenn man - die Nullen ausgeklammert - auf eine Zahl stößt, die nicht größer ist, als ihr Vorgänger. Auch könnte man überlegen, ob man das Auftauchen von negativen Zahlen dulden will oder eine Exception wirft. Bei der Folge -10, 0, 20 wäre sonst nicht klar, ob die Null eine reguläre Zeilennummer ist oder eine zu füllende Lücke.

*Die endOfList-Behandlung kannst du dir sparen, wenn du maxLineNo so previousNo + ((gap + 1) * defaultIncrement) oder vielleicht noch besser so previousNo + defaultIncrement + (gap * defaultIncrement) berechnest.

*In der Schleife mit y als Laufvariable kannst du besser i als Laufvariable verwenden. Du weißt ja, dass du bis itemNo laufen musst. Außerdem ist das i dann schon so erhöht, dass der gerade gefüllte Bereich von der äußeren Schleife nicht unnötigerweise nochmal durchlaufen wird.

herbivore