mhm bo używasz next! które zmienia wartość “w miejscu” a nie tylko zwraca zmienioną wartość
pomyśl tylko czy na pewno nie lepiej jednak pisać odrobinę bardziej funkcyjnie?
[quote=zlw]mhm bo używasz next! które zmienia wartość “w miejscu” a nie tylko zwraca zmienioną wartość
pomyśl tylko czy na pewno nie lepiej jednak pisać odrobinę bardziej funkcyjnie?[/quote]
Bo e to jest kopia, a nie tab[i].
Nie ogarniam pisania funkcyjnego, jak chcesz to napisz przykład.
No chociażby pierwszy przykład (ten z split, map, join) jest napisany funkcyjnie, nigdzie nie zmieniasz “w miejscu” wartości, operujesz tylko na tym co zwróciła Ci poprzednia metoda.
Nie wiem jakie tam masz wykonywać operacje, ale dla tej konkretnej wydaje mi się, że najlepiej będzie to zrobić tak jak napisałem na początku:
No okej, ale ten sposób też nie jest jakiś koszmarnie wolny:
[code=ruby]require ‘benchmark’
Benchmark.bm(10) do |bm|
[1000, 10_000, 100_000, 1_000_000].each do |i|
bm.report("#{i} iterations: ") { (‘abc’*i).split(’’).map(&:next).join }
end
end
[quote=zlw]No okej, ale ten sposób też nie jest jakiś koszmarnie wolny:
[code=ruby]require ‘benchmark’
Benchmark.bm(10) do |bm|
[1000, 10_000, 100_000, 1_000_000].each do |i|
bm.report("#{i} iterations: ") { (‘abc’*i).split(’’).map(&:next).join }
end
end
Jeżeli odnosisz się do tego postu co do liniowego dostępu to zostało to poprawione. Zresztą gdzieś na forum jest dyskusja dotycząca tego problemu. Ktoś z forum zgłosił błąd i zostało to naprawione.
Jeżeli masz tą operację zrobić raz to w sumie pal sześć czas - dawno już byś to napisał i 10 razy odpalił zamiast rozmyślać jak będzie najszybciej
p.s.
[quote=goozzik]Jeśli chcesz żeby ci to działało z each_char
t = "asd"
t.each_char {|e| t[t.index(e)] = e.next}
puts t # => "bte"
[/quote]
moim zdaniem to strasznie nieczytelny kod i zupełnie nie idiomatyczny. no i zmieniasz w miejscu wartość, a nie widać tego na pierwszy rzut oka - nie ma metod z ! które zazwyczaj właśnie to oznaczają.
Jeszcze jedna rzecz mnie zastanawia.
Czemu tab[i].next! nie działa?
Da się wywołać destrukcyjną metodę(w sensie czy da się ZMIENIĆ wartość) na stringu w iteracji?
Ehh, ale czemu tak się upierasz przy tej zmianie w miejscu? Przyjdzie Ci kiedyś napisać współbieżną czy wielowątkową aplikację i będą z tego powodu same problemy.
Ruby ma pewne korzenie w językach funkcyjnych (stąd normalnie metody zwracają kopie a nie zmieniają wartość) i idiomatyczny ruby zdecydowanie bardziej przypomina funkcyjny niż imperatywny kod. To nie jest trudne a i kod zazwyczaj jest czytelniejszy i bardziej zwięzły
W Rubim metoda each_char wrzuca po prostu do bloku kopię znaku, a nie jego referencję - w przeciwieństwie do metody each dla tablicy, dlatego zasadniczo nie da się tego zrobić elegancko z wykorzystaniem modyfikacji “w miejscu”. Podejście zlw jest jak najbardziej eleganckie - ale oczywiście możesz się upierać przy swojej koncepcji.