Niemutowalna torba

Niemutowalna torba
MY
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 25
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?

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • 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.

MY
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 25
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źć

Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
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)).

jarekr000000
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: U krasnoludów - pod górą
  • Postów: 4712
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ć.

Charles_Ray
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1910
1

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

semicolon
  • Rejestracja: dni
  • Ostatnio: dni
  • 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: dni
  • Ostatnio: dni
  • 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().

KamilAdam
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Silesia/Marki
  • Postów: 5550
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.

MY
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 25
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.

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.