Dim myList = New List(Of IComparable)(New Integer() {1, 2, 3, 4, 5})
Console.WriteLine(myList.IsSuccsessive()) 'Sollte True sein
Dim myList2 = New List(Of IComparable)(New Double() {1, 2, 30, 4, 5})
Console.WriteLine(myList2.IsSuccsessive()) 'Sollte False sein
'Gemischte Liste
Dim myList3 = New List(Of IComparable)
myList3.Add(1) 'int
myList3.Add(2) 'int
myList3.Add(2.5) 'Double
myList3.Add(3) 'int
Console.WriteLine(myList.IsSuccsessive()) 'Sollte True seinpublic static bool IsSuccsessive<T>(this IEnumerable<T> input) where T : IComparable
{
if ((input==null) || (input.Count()==0)) return true;
var oldVal = default(T);
foreach (var val in input)
{
if (oldVal.CompareTo(val) == 1) return false;
oldVal = val;
}
return true;
}
|
|
public static bool IsSuccsessive<T>(this IEnumerable<T> input) where T : IComparable
{
if ((input == null) || (input.Count() == 0)) return true;
var oldVal = input.First();
foreach (var val in input.Skip(1))
{
if (oldVal.CompareTo(val) > 0) return false;
oldVal = val;
}
return true;
}
|
|
|
An das kleine Skip habe ich nicht gedacht. Das war des Rätsels Lösung. Klasse thx
– Thomas Sczyrba 23.03.2011
|
||
|
es hat auch ohne skip funktioniert ABER: -> kommentar in meiner antwort
– nabuchodonossor 23.03.2011
|
||
| 2 |
Stimmt, es funktioniert auch ohne Skip - solange aufeinderfolgende gleiche Werte ok sind. Dann ist Skip einfach nur eine Optimierung (sowohl der Laufzeit als auch der Verständlichkeit). Wenn auf "strenges" Aufsteigen geprüft werden soll, ist Skip aber nötig.
Übrigens: CompareTo garantiert nicht, dass es 1 liefert. Deshalb sollte das Ergebnis nur mit 0 verglichen werden, nicht mit 1. Habe mein Beispiel entsprechend angepasst. – Matthias Hlawatsch 23.03.2011
|
|
|
Nochmal in der Doku nachgesehen, du hast recht, es könnte auch jeder andere Wert grösser 0 daherkommen. Was aber dann wiederum bedeutet, dass die Abfrage nicht > 0, sondern < 1 sein sollte - FALLS aufeinanderfolgende gleichbleibende Werte erlaubt sind.
– nabuchodonossor 23.03.2011
|
||
|
ja, und noch mal herumprobiert, die Methode mit skip ist natürlich elegant! das mit < und > ist natürlich auch so eine sache: ich hab in meinen tests nämlich nicht den alten mit dem neuen, sondern den neue mit dem alten verglichen ... da komme ich schon mal durcheinander.
– nabuchodonossor 23.03.2011
|
||
|
Guter Hinweis mit dem CompareTo vergleichsoperator. Meine Ursprünglicher Version mit ==1 ist auf die Nase gefallen. Damit geprüft wird ob aufsteigende Werte enthalten sind (zweimal die gleiche Zahl hintereinander ist nicht aufsteigend) benutze ich jetzt : oldVal.CompareTo(val) > -1 :-)
– Thomas Sczyrba 23.03.2011
|
||
|
Freut mich, dass ich helfen konnte :-)
Auch wenn es funktional äquivalent ist: schreib lieber oldVal.CompareTo(val) >= 0. Liest sich leichter - jedenfalls gehe ich mal davon aus, dass ich nicht der einzige bin, der sich die Verwendung von CompareTo so merkt: linkerOperand Operator rechterOperand entspricht linkerOperand.CompareTo(rechterOperand) Operator 0. Der Punkt ist, dass ich dann beim Denken/Schreiben/Lesen den gleichen Operator verwende, während in Deiner Variante das geschriebene ">" ein logisches ">=" bedeutet. – Matthias Hlawatsch 23.03.2011
|
||
|
Und ausserdem funktioniert es bei mir, mehr oder weniger. Die Werte 10, 11, 13 ergeben true, obwohl sie nicht forlaufend sind, weil comparto ja nur sagt ist grösser oder kleiner oder gleich, aber nicht sagt, wieviel grösser oder kleiner.
– nabuchodonossor 23.03.2011
|
||
| 1 |
Und das Hauptproblem sehe ich in der Vermischun von int und double: Wenn 11, 12, 13 true ist, wirst du wahrscheinlich auch haben wollen, dass 11.0, 12.0, 13.0 true ergibt. Aber meiner Ansicht nach könnte auch 11.001, 11.002, 11.003 eine fortlaufende Kette bilden.
Dalso da würde ich nochmal drüber nachdenken. – nabuchodonossor 23.03.2011
|
|
|
Ja das mit den ERSTEN Eintrag ist korrekt. Das in Verbindung mit Skip hats gebracht. Mit "fortlaufend" war gemeint das der Nachfolgende Wert nicht kleiner sein darf wie der vorhergehende. Die Abstände zwischen den Werten sind hierbei egal
– Thomas Sczyrba 23.03.2011
|
||
|
Wenn der nachfolgende Wert GLEICH sein darf, musst du das von == 1 noch auf < 1 ändern.
– nabuchodonossor 23.03.2011
|
||
| 2 |
"nicht GLEICH sein darf", wolltest Du schreiben, oder? "< 1" führt dazu, dass ein Ergebnis von 0, also Gleichheit, die Schleife mit false abbricht, d.h. aufeinderfolgende gleiche Werte ergeben false als Ergebnis.
Und, wie ich bei meiner Antwort angemerkt habe: es ist besser, mit 0 zu vergleichen. Laut Doku kann CompareTo irgendwas zurückgeben, nur das Vorzeichen ist garantiert. – Matthias Hlawatsch 23.03.2011
|
|
'ich würde anstelle von:'
var oldVal = default(T);
'etwas wie:'
var oldval=input[0];
'benutzen.
|
|
| 1 |
Egal wie man die Logik formuliert, es kommt bei dem Code Beispiel solange true raus, solange die nächste Zahl größer ist, also die Methode IsSuccessive sagt nur "aufsteigend" oder eben nicht, nicht aber zusammenhängend aufsteigend.
– nabuchodonossor 23.03.2011
|
|
| 1 |
Da Thomas speziell nach der Initialisierung beim ersten Schleifendurchlauf gefragt hat, gehe ich mal davon aus, dass er mit dem Code innerhalb der Schleife zufrieden ist. Das Beispiel mit double würde sonst ja auch keinen Sinn ergeben - 2.5 hat keinen Nachfolger. Dann leistet die Methode aber tatsächlich 'nur' "IstAufsteigend".
– Matthias Hlawatsch 23.03.2011
|