Jakiś czas temu pod koniec jednego z programistycznych rajdów od świtu do świtu pojawiło się zapotrzebowanie na funkcjonalność "masz tu liczbę i zwróć X jej ostatnich cyfr w postaci stringa; w razie potrzeby wypełnij jego początek zerami". Wydaje się banalne i byłem pewny, że w ciągu kwadransa załatwię to odpowiednim formatowaniem integera.
Po półtorej godziny (sic!) lektury MSDN, różnych blogów i popełniania głupich eksperymentów nadal byłem w kropce. Jest to szczególnie irytujące w sytuacji, gdy taka pierdoła będąca ostatnią rzeczą zaplanowaną na aktualną sesję przeciąga się w nieskończoność bezlitośnie kradnąc sen. 10 minut po postanowieniu "screw you, int.ToString()!" miałem gotową metodę:
1: private static string TakeLastXDigits(int number, int length) 2: { 3: string formatted = number.ToString("D" + length); 4: return string.Join(string.Empty, 5: formatted.Skip(formatted.Length - length) 6: .Select(x => x.ToString() 7: ).ToArray()); 8: }
Wewnętrzne czułem, że to jak jechanie z Warszawy do Moskwy przez Paryż (ależ trafna geograficzna metafora, a niech mnie!).
No i miałem rację. Zapytany o zdanie ziom potrzebował kilku sekund na usunięcie z tego potwora niesamowitego przerostu formy nad treścią i doprowadzenie go do postaci:
1: private static string TakeLastXDigits(int number, int length) 2: { 3: string formatted = number.ToString("D" + length); 4: return formatted.Substring(formatted.Length - length); 5: }
Pytanie: jak to uprościć jeszcze bardziej? Czy da się to załatwić przekazaniem odpowiedniego formatu do int.ToString()?
private static string TakeLastXDigits2(int number, int length)
{
return (number%(Math.Pow(10,length))).ToString();
}
Teraz widze, ze moja f. nie dopelni zerami liczby jezeli jest mniej znakow niz dlugosc stringu.
@klm_: dodaj jeszcze .PadLeft(length,"0") i będzie ok :)
chyba to najprostszy sposób ;)
jest coś takiego jak:
String.Format("{0:DX}", 125)
gdzie X to ilość znaków do której z lewej strony cyfra ma zostać dopełniona zerami. ona jednak nie potrafi obciąć – trzeba by dodatkowo przycinać stringa.. więc nie wiem czy najkrótszy nie pozostanie sposób "zioma" ;)
W sumie wszystkie te propozycje maja wspolna wade – trzeba je zamknac do osobnej metody:). Mialem nadzieje na przekazanie odpowiedniego formatu do int.ToString() i tyle… ale dzieki za pomysly.
Jeśli chodzi Ci o coś, co zajmie mniej linijek to oczywiście się da w C# itp, ale jeśli chcesz, żeby kod wynikowy był jak najszybszy to sorki, tylko C (a dla zyskania kilku nanosekund to może być i assembeler).
.NET do takich zadań używają tylko kmiotki, które nie potrafią programować w języku, który wymaga logicznego myślenia.
.NET i C# są świetne do prostych aplikacji okienkowych, ale jeśli ktoś chce coś, co żre mniej pamięci i działą dużo szybciej to C się kłania (ew, assembler, gdy na jedną platformę).
@zmyślony:
Nie zalezy mi na kilku nanosekundach szybciej czy 10 bajtach pamięci mniej tylko na czytelnym kodzie… ale jestem tylko kmiotkiem piszącym proste aplikacje okienkowe :).
Nanosekundy dotyczyły różnic pomiędzy C a assemblerem (czyli jeszcze dochodzi czytanie ze zrozumieniem), ponieważ różnica pomiędzu C a C# w szybkości działania jest jak pomiędzy Boltem a ślimakiem, który na dodatek nosi na sobie cały piękny Wilanów.
A jeśli chodzi o czytelny kod: to co jest bardziej czytelne: kod który być może ładnie wygląda, ale wymaga znajomości wielu dziwnych nieprzenoszalnych bilbiotek czy kod, który używa powszechnie znanych bibliotek i funkcji, użyteczny pod Windą, linuksem czy jakimś embedded, mimo, że zajmie dwie, trzy liniki więcej ?
PS. nie jestem przeciw .NET, sam go używam, ale trzeba oddzielić "piękny kod" od "szybkiego" i "przenoszalnego".
PS2. @procent czy @dotnetomaniak, –
"kmiotek" – to nie było personalnie do Was, bo akurat Was nie znam, ale to było do wszystkich, którzy używają jednego języka do wszystkich zastosowań, nawet jeśli inne języki byłyby "fajniejsze" dla procka czy systemu.
@zmyślony:
dotnetomaniak to strona http://www.dotnetomaniak.pl, a ja sie nigdy na nic nie obrazam wiec cool:).
Roznica w szybkosci miedzy c a .net… oczywiscie ze jest i kazdy uzywajacy .net zdaje sobie z tego sprawe. po prostu ta roznica jest w ogromnej wikeszosci przypadkow bez znaczenia. Szybkosc stworzenia CZYTELNEGO i LATWIEJSZEGO W UTRZYMANIU kodu jest powodem, dla ktorego c# nadaje sie do wiekszej liczby "ogolnych" zasstosowan niz c. I wymyslanie od "kmiotkow" nie ma zadnego sensu, to jest po prostu naturalna ewolucja podejscia do tworzenia oprogramowania.
Skoro ‘szybkosc’ mamy za soba, to teraz "piękno": dla mnie piekny jest kod, ktory rozumiem podczas czytania. I piekny jest kod, ktory nie wymaga modyfikacji w milionie miejsc podcza dodawania nowych bądź naprawiania istniejacych funkcjonalnosci.
A "przenaszalnosc"… nie rozumiem co ma tu do rzeczy. Kod napisany w c# wykona sie na windows, wykona sie na windows mobile (w ograniczonym zakresie), wykona sie na linuxie dzieki Mono (co trzeba oczywiscie przetestowac), jest uzywalny w aplikacjach silverlight… a tajemnica chyba nie jest żadna, że Java oferuje wiekszy stopien przenaszalnosci na rozne platformy.
Ale dyskusje o wyzszosci .net nad javą, C nad .net, assemblera nad pythonem, flasha nad silverlightem czy jakiejkolwiek innej technologii nad jakakolwiek inna technologia uwazam za glupie, bo kazda ma swoje zastosowania, wady i zalety. Gdyby tak nie bylo to nikt by jej nie uzywal.
Może troszke z innej beczki ale dla mnie kiedyś objawieniem była taka konstrukcja T-SQL owa
RIGHT(‘00000000’+@i,8)