Próbuję posortować tablicę liczb, które są ciągami znaków i chciałbym, aby posortowano je numerycznie.
Problem polega na tym , że nie mogę zamienić liczb na int .
Oto kod:
string[] things= new string[] { "105", "101", "102", "103", "90" };
foreach (var thing in things.OrderBy(x => x))
{
Console.WriteLine(thing);
}
wyjście: 101, 102, 103, 105, 90
Chciałbym: 90, 101, 102, 103, 105
EDYCJA: Wyjście nie może być 090, 101, 102 ...
Zaktualizowano przykładowy kod, aby mówił „rzeczy” zamiast „rozmiary”. Tablica może wyglądać mniej więcej tak:
string[] things= new string[] { "paul", "bob", "lauren", "007", "90" };
Oznacza to, że należy posortować alfabetycznie i według numerów:
007, 90, Bob, Lauren, Paul
image10
przyjść późniejimage2
? PowinienJanuary
przyjść wcześniejFebruary
?Odpowiedzi:
Przekaż niestandardową funkcję porównującą do OrderBy. Enumerable.OrderBy pozwoli ci określić dowolną porównywalną.
Oto jeden ze sposobów, aby to zrobić:
źródło
IsNumeric
Metoda jest zła, wyjątek napędzany kodowanie jest zawsze złe. Użyjint.TryParse
zamiast tego. Wypróbuj swój kod z dużą listą, a zajmie to wieczność.Po prostu uzupełnij zerami do tej samej długości:
źródło
sizes
również nie zadziała, ponieważ wynik jest innego typu. Odpowiedź jest trochę krótka, ponieważ druga linia pokazuje wynik jako wyrażenie, ale czytelnik musi coś z tym zrobić. Dodałem kolejne przypisanie zmiennej, aby było to bardziej zrozumiałe.A co powiesz na to ...
źródło
"b", "ab", "101", "103", "bob", "abcd"
.Wartość to ciąg
Pracuje
źródło
string[] { "Object 1", "Object 9", "Object 14" }
"b", "ab", "101", "103", "bob", "abcd"
.W oknach istnieje natywna funkcja
StrCmpLogicalW
, która porównuje w łańcuchach liczby jako liczby zamiast liter. Łatwo jest utworzyć moduł porównujący, który wywołuje tę funkcję i używa jej do porównań.Działa nawet na łańcuchach zawierających zarówno tekst, jak i liczby. Oto przykładowy program, który pokaże różnicę między domyślnym sortowaniem a
StrCmpLogicalW
sortowaniemktóre wyjścia
źródło
-1 0 10 2
jest sortowany jako0 -1 2 10
Spróbuj tego
Uwaga: będzie to pomocne, gdy wszystkie można zamienić na ciągi znaków typu int .....
źródło
ToList()
przed =>sizes.ToList().OrderBy(x => Convert.ToInt32(x))
Wydaje mi się, że będzie to znacznie lepsze, jeśli będzie zawierał jakiś numer w ciągu. Mam nadzieję, że to pomoże.
PS: Nie jestem pewien wydajności lub skomplikowanych wartości ciągów, ale działało dobrze, coś takiego:
lorem ipsum
lorem ipsum 1
lorem ipsum 2
lorem ipsum 3
...
lorem ipsum 20
lorem ipsum 21
źródło
Mówisz, że nie możesz zamienić liczb na int, ponieważ tablica może zawierać elementy, których nie można przekonwertować na int, ale nie ma nic złego w próbowaniu:
Następnie porównaj w ten sposób:
Wyjście: 007, 90, 90, 101, 102, 103, 105, bob, lauren, paul
źródło
Wydaje się to dziwna prośba i zasługuje na dziwne rozwiązanie:
źródło
Ta witryna omawia sortowanie alfanumeryczne i posortuje liczby w sensie logicznym zamiast ASCII. Bierze również pod uwagę alfy wokół niego:
http://www.dotnetperls.com/alphanumeric-sorting
PRZYKŁAD:
Kod wygląda następująco:
źródło
Odpowiedź udzielona przez Jeffa Paulsena jest poprawna, ale
Comprarer
można ją znacznie uprościć:To działa, ponieważ jedyną rzeczą, która jest sprawdzana pod kątem wyniku,
Comparer
jest to, czy wynik jest większy, mniejszy lub równy zero. Można po prostu odjąć wartości od innych i nie trzeba zajmować się wartościami zwracanymi.Również
IsNumeric
metoda nie powinna używać opcjitry
-block i może przynieść korzyściTryParse
.A dla tych, którzy nie są pewni: ten Porównywacz posortuje wartości w taki sposób, aby wartości nienumeryczne były zawsze dołączane na końcu listy. Jeśli ktoś chce je na początku,
if
należy zamienić drugi i trzeci blok.źródło
Spróbuj tego :
źródło
arr = arr.OrderBy (x => x, new NaturalSort ()). ToArray ();
Powodem, dla którego potrzebowałem, było umieszczenie go w katalogu, którego nazwy plików zaczynały się od numeru:
źródło
Teraz posortuj listy i połącz je z powrotem ...
Próbowałem tylko wnieść swój wkład w to interesujące pytanie ...
źródło
Moje preferowane rozwiązanie (jeśli wszystkie ciągi są tylko numeryczne):
źródło
źródło
Poszerzenie odpowiedzi Jeffa Paulsena. Chciałem się upewnić, że nie ma znaczenia, ile liczb lub grup znaków znajduje się w łańcuchach:
Wziąłem również SplitCharsAndNums z SO Page po poprawieniu go, aby poradzić sobie z nazwami plików.
źródło
Mimo że jest to stare pytanie, chciałbym podać rozwiązanie:
Woha całkiem proste, prawda? :RE
źródło
źródło