Niemutowalna torba

Niemutowalna torba
MY
  • Rejestracja:około 5 lat
  • Ostatnio:5 miesięcy
  • Postów:24
0

Cześć,

wyobrażam sobie klasę Bag, która zwiera jakieś elementy (nie da się sprawdzić jakie) i na której mogę zawołać metodę .take(3). W wyniku chciałbym dostać trzy losowe elementy z mojej torby + nowy obiekt Bag z aktualnym stanem. Jak najlepiej zaprojektować takie API? Czy w ogóle jest sens, żeby ta klasa były niemutowalna?

PerlMonk
Tytuł wątku to jakiś troll, prawda? :D
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
2

Czy w ogóle jest sens, żeby ta klasa były niemutowalna?

Nie rozumiem pytania. Jeśli potrzebujesz coś takiego, to takie coś napisz :) Przecież sensowność wynika z potrzeby "biznesowej".
API? Najprościej zwracać jakiś pewnie jakies Either<Error, TakeResult> gdzie TakeResult zawiera nowego Bag i jakiś BagSlice z tymi wybranymi elementami.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
MY
  • Rejestracja:około 5 lat
  • Ostatnio:5 miesięcy
  • Postów:24
0
Shalom napisał(a):

Czy w ogóle jest sens, żeby ta klasa były niemutowalna?

Nie rozumiem pytania. Jeśli potrzebujesz coś takiego, to takie coś napisz :) Przecież sensowność wynika z potrzeby "biznesowej".
API? Najprościej zwracać jakiś pewnie jakies Either<Error, TakeResult> gdzie TakeResult zawiera nowego Bag i jakiś BagSlice z tymi wybranymi elementami.

No właśnie zastanawia mnie potem kwestia użycia takiego API, gdzie "result" mam tak głęboko zaszyty. Szukam jakiegoś przykładu gdzie jest to rozwiązane podobnie, ale nie mogę znaleźć

edytowany 1x, ostatnio: mythflame
Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 6 godzin
3

Niemutowalne kolekcje mają np metodę do podziału kolekcji w pewnym miejscu, np io.vavr.collection.Vector.splitAt. Zwraca parę wektorów. W twoim przypadku torba.splitAt mogłoby zwracać dwie torby - jedną z 3 elementami i drugą bez tych 3 elementów. Potem na pierwszej robisz np .toList czy coś w ten deseń i już mamy kolekcję, której zawartość można sprawdzać wprost.

Co do losowości to nawet jeśli byłaby jakaś to powinna być powtarzalna, tak by zachodził warunek. x.take(3).equals(x.take(3)).


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 8 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
2

W kotlinie mosz w standardzie Pair więc możesz mieć Bag<T>{ fun take(i:Int) : Pair<List<T>,Bag> }
Z tym, że własny typ też ma zalety. Opakowanie tego w Either lub Option też jest raczej dobrym pomysłem.

To, że będzie zaszyty to nie jest problem - dzięki temu lepiej widać w API co może być rezultatem i jak z tym postępować.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000
Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:około 11 godzin
  • Postów:1875
1

Projekt API: fun take(n: Int): Bag, gdzie nowy Bag może mieć maksymalnie n elementów


”Engineering is easy. People are hard.” Bill Coughran
edytowany 1x, ostatnio: Charles_Ray
Zobacz pozostałe 4 komentarze
Shalom
@Charles_Ray: tak jak pisaliśmy wyżej, zwracając dwie nowe kolekcje, jedną która ma te wybrane elementy, a drugą która zawiera pozostałe. Nie traktuj tego jak "odejmowanie" a raczej jako partition.
Charles_Ray
No spoko, dzięki. A to jest to czego chciał op?
Shalom
W wyniku chciałbym dostać trzy losowe elementy z mojej torby + nowy obiekt Bag z aktualnym stanem
Charles_Ray
No to moje rozwiązanie (API) tylko ze trzeba w wyniku oprócz nowej torby dać listę
Shalom
Czyli krotkę/klasę na wyniki, o której wszyscy tu piszą :D
semicolon
  • Rejestracja:ponad 5 lat
  • Ostatnio:prawie 5 lat
  • Postów:114
0

Próbujesz za pomocą jednej metody zrobić wszystko - to dobre rozwiązanie na szybko, ale w praktyce jest mniej intuicyjne.

Twoje API byłoby prostsze gdybyś potraktował bag jak kolekcje.

Dobrze byłoby, gdyby po Twoim bagu dało się iterować, wówczas mógłbyś łatwo odczytać wartości jakie są w nim lub też przekonwertować na inną kolekcję.

Na bagu jak zrobisz randomTake wtedy ten bag zwróci Ci mniejszy bag.

PI
  • Rejestracja:ponad 9 lat
  • Ostatnio:4 miesiące
  • Postów:2787
0

A może niech Twoja klasa Bag opakowuje javowy Set (mieć set jako pole klasy) i taka metoda take(3) by brała 3 pierwsze elementy setu (a że jest to np HashSet, to będą to losowe elementy) i robiła na nich .remove().

Wibowit
To na pewno nie będzie niemutowalna kolekcja danych, no chyba że za każdym razem cały HashSet będzie kopiowany.
PI
Autor pytał, czy jest sens, żeby ta torba była niemutowalna ;) więc ma tutaj wybór
KamilAdam
  • Rejestracja:ponad 6 lat
  • Ostatnio:27 dni
  • Lokalizacja:Silesia/Marki
  • Postów:5505
0
mythflame napisał(a):

Cześć,

wyobrażam sobie klasę Bag, która zwiera jakieś elementy (nie da się sprawdzić jakie) i na której mogę zawołać metodę .take(3). W wyniku chciałbym dostać trzy losowe elementy z mojej torby + nowy obiekt Bag z aktualnym stanem. Jak najlepiej zaprojektować takie API? Czy w ogóle jest sens, żeby ta klasa były niemutowalna?

Jak piszesz o niemutowalności to najlepiej sprawdzić jak zrobili to w Haskellu. Dla List jest funkcja splitAt :: Int -> [a] -> ([a], [a]) która pobiera index typu Int i listę a zwraca parę list. Pierwsza zawiera elementy przed tym indeksem, a druga resztę. Dodatkowo jest dopisek że funkcja splitAt(index list) jest ekwiwalentem (take (index list), drop(index list)). Więc IHMO api zaprojektowane przez Ciebie jak najbardziej ma sens.


Mama called me disappointment, Papa called me fat
Każdego eksperta można zastąpić backendowcem który ma się douczyć po godzinach. Tak zostałem ekspertem AI, Neo4j i Nest.js . Przez mianowanie
MY
  • Rejestracja:około 5 lat
  • Ostatnio:5 miesięcy
  • Postów:24
0

Dzięki za głosy i fajne przykłady. Zrobię własny typ zawierający nowy Bag + listę "wyjętych" elementów, ma to sens

Wibowit napisał(a):

Co do losowości to nawet jeśli byłaby jakaś to powinna być powtarzalna, tak by zachodził warunek. x.take(3).equals(x.take(3)).

Będę "mieszał" elementy gdzieś wcześniej, a przy take wyciągnę tylko N kolejnych. Powinno być okej.

edytowany 1x, ostatnio: mythflame

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.