EnumerableOperations.vala 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. using Astralis;
  2. using Invercargill;
  3. using Invercargill.DataStructures;
  4. /**
  5. * EnumerableOperations Example
  6. *
  7. * Demonstrates various LINQ-like operations available in Invercargill Enumerable.
  8. * This example shows filtering, mapping, grouping, and aggregation operations.
  9. */
  10. // Root handler
  11. class RootHandler : Object, RouteHandler {
  12. public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
  13. return new BufferedHttpResult.from_string(
  14. """Enumerable Operations Demo
  15. This example demonstrates various LINQ-like operations available in Invercargill Enumerable:
  16. Endpoints:
  17. GET /filter - Filtering examples
  18. GET /map - Mapping/Projection examples
  19. GET /group-by - Grouping examples
  20. GET /aggregate - Aggregation examples
  21. GET /sort - Sorting examples
  22. GET /set-operations - Set operations (union, intersection, etc.)
  23. GET /advanced - Advanced operations (zip, partition, etc.)
  24. """
  25. );
  26. }
  27. }
  28. // Filtering examples
  29. class FilterHandler : Object, RouteHandler {
  30. public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
  31. var numbers = Wrap.array<int>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
  32. var parts = new Series<string>();
  33. parts.add_start("Original: ");
  34. parts.add_start(enumerable_int_to_string(numbers.as_enumerable()));
  35. parts.add_start("\n\n");
  36. // Filter even numbers
  37. var even = numbers.as_enumerable()
  38. .where(n => n % 2 == 0);
  39. parts.add_start("Even numbers: ");
  40. parts.add_start(enumerable_int_to_string(even));
  41. parts.add_start("\n");
  42. // Filter odd numbers
  43. var odd = numbers.as_enumerable()
  44. .where(n => n % 2 != 0);
  45. parts.add_start("Odd numbers: ");
  46. parts.add_start(enumerable_int_to_string(odd));
  47. parts.add_start("\n");
  48. // Filter numbers greater than 5
  49. var greater_than_5 = numbers.as_enumerable()
  50. .where(n => n > 5);
  51. parts.add_start("Greater than 5: ");
  52. parts.add_start(enumerable_int_to_string(greater_than_5));
  53. parts.add_start("\n\n");
  54. // Chained filters
  55. var filtered = numbers.as_enumerable()
  56. .where(n => n > 3)
  57. .where(n => n < 8);
  58. parts.add_start("Between 3 and 8: ");
  59. parts.add_start(enumerable_int_to_string(filtered));
  60. var result = parts.to_immutable_buffer()
  61. .aggregate<string>("", (acc, s) => acc + s);
  62. return new BufferedHttpResult.from_string(result);
  63. }
  64. }
  65. // Mapping/Projection examples
  66. class MapHandler : Object, RouteHandler {
  67. public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
  68. var numbers = Wrap.array<int>({1, 2, 3, 4, 5});
  69. var parts = new Series<string>();
  70. parts.add_start("Original: ");
  71. parts.add_start(enumerable_int_to_string(numbers.as_enumerable()));
  72. parts.add_start("\n\n");
  73. // Square each number
  74. var squared = numbers.as_enumerable()
  75. .select<int>(n => n * n);
  76. parts.add_start("Squared: ");
  77. parts.add_start(enumerable_int_to_string(squared));
  78. parts.add_start("\n");
  79. // Double each number
  80. var doubled = numbers.as_enumerable()
  81. .select<int>(n => n * 2);
  82. parts.add_start("Doubled: ");
  83. parts.add_start(enumerable_int_to_string(doubled));
  84. parts.add_start("\n");
  85. // Convert to string
  86. var as_strings = numbers.as_enumerable()
  87. .select<string>(n => n.to_string());
  88. parts.add_start("As strings: ");
  89. parts.add_start(enumerable_string_to_string(as_strings));
  90. parts.add_start("\n\n");
  91. // With index
  92. var with_index = numbers.as_enumerable()
  93. .with_positions()
  94. .select<string>(pair => @"$(pair.item) at index $(pair.position)");
  95. parts.add_start("With index: ");
  96. parts.add_start(enumerable_string_to_string(with_index));
  97. var result = parts.to_immutable_buffer()
  98. .aggregate<string>("", (acc, s) => acc + s);
  99. return new BufferedHttpResult.from_string(result);
  100. }
  101. }
  102. // Grouping examples
  103. class GroupByHandler : Object, RouteHandler {
  104. public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
  105. var words = Wrap.array<string>({
  106. "apple", "banana", "cherry", "apricot",
  107. "blueberry", "blackberry", "coconut"
  108. });
  109. var parts = new Series<string>();
  110. parts.add_start("Words: ");
  111. parts.add_start(enumerable_string_to_string(words.as_enumerable()));
  112. parts.add_start("\n\n");
  113. // Group by first letter
  114. var grouped = words.as_enumerable()
  115. .group_by<string>(w => w.get_char(0).to_string());
  116. parts.add_start("Grouped by first letter:\n");
  117. grouped.iterate((grouping) => {
  118. parts.add_start(@" $(grouping.key): ");
  119. parts.add_start(enumerable_string_to_string(grouping.to_immutable_buffer()));
  120. parts.add_start("\n");
  121. });
  122. var result = parts.to_immutable_buffer()
  123. .aggregate<string>("", (acc, s) => acc + s);
  124. return new BufferedHttpResult.from_string(result);
  125. }
  126. }
  127. // Aggregation examples
  128. class AggregateHandler : Object, RouteHandler {
  129. public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
  130. var numbers = Wrap.array<int>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
  131. var parts = new Series<string>();
  132. parts.add_start("Numbers: ");
  133. parts.add_start(enumerable_int_to_string(numbers.as_enumerable()));
  134. parts.add_start("\n\n");
  135. // Count
  136. var count = numbers.as_enumerable().count();
  137. parts.add_start(@"Count: $count\n");
  138. // Sum using aggregate
  139. var sum = numbers.as_enumerable()
  140. .aggregate<int>(0, (acc, n) => acc + n);
  141. parts.add_start(@"Sum: $sum\n");
  142. // Average
  143. var avg = (double)sum / count;
  144. parts.add_start(@"Average: $avg\n");
  145. // Min
  146. var min = numbers.as_enumerable().min(n => n);
  147. parts.add_start(@"Min: $min\n");
  148. // Max
  149. var max = numbers.as_enumerable().max(n => n);
  150. parts.add_start(@"Max: $max\n");
  151. // First
  152. var first = numbers.as_enumerable().first();
  153. parts.add_start(@"First: $first\n");
  154. // Last
  155. var last = numbers.as_enumerable().last();
  156. parts.add_start(@"Last: $last\n");
  157. var result = parts.to_immutable_buffer()
  158. .aggregate<string>("", (acc, s) => acc + s);
  159. return new BufferedHttpResult.from_string(result);
  160. }
  161. }
  162. // Sorting examples
  163. class SortHandler : Object, RouteHandler {
  164. public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
  165. var numbers = Wrap.array<int>({5, 2, 8, 1, 9, 3, 7, 4, 6, 10});
  166. var parts = new Series<string>();
  167. parts.add_start("Original: ");
  168. parts.add_start(enumerable_int_to_string(numbers.as_enumerable()));
  169. parts.add_start("\n\n");
  170. // Sort ascending
  171. var sorted_asc = numbers.as_enumerable()
  172. .order_by<int>(n => n);
  173. parts.add_start("Ascending: ");
  174. parts.add_start(enumerable_int_to_string(sorted_asc));
  175. parts.add_start("\n");
  176. // Sort descending
  177. var sorted_desc = numbers.as_enumerable()
  178. .order_by_descending<int>(n => n);
  179. parts.add_start("Descending: ");
  180. parts.add_start(enumerable_int_to_string(sorted_desc));
  181. var result = parts.to_immutable_buffer()
  182. .aggregate<string>("", (acc, s) => acc + s);
  183. return new BufferedHttpResult.from_string(result);
  184. }
  185. }
  186. // Set operations
  187. class SetOperationsHandler : Object, RouteHandler {
  188. public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
  189. var set1 = Wrap.array<int>({1, 2, 3, 4, 5});
  190. var set2 = Wrap.array<int>({4, 5, 6, 7, 8});
  191. var parts = new Series<string>();
  192. parts.add_start("Set 1: ");
  193. parts.add_start(enumerable_int_to_string(set1.as_enumerable()));
  194. parts.add_start("\n");
  195. parts.add_start("Set 2: ");
  196. parts.add_start(enumerable_int_to_string(set2.as_enumerable()));
  197. parts.add_start("\n\n");
  198. // Union (concat)
  199. var union = set1.as_enumerable().concat(set2.as_enumerable());
  200. parts.add_start("Union: ");
  201. parts.add_start(enumerable_int_to_string(union));
  202. parts.add_start("\n");
  203. // Common (intersection)
  204. var common = set1.as_enumerable().common(set2.as_enumerable());
  205. parts.add_start("Common: ");
  206. parts.add_start(enumerable_int_to_string(common));
  207. parts.add_start("\n");
  208. // Non-common (difference)
  209. var diff = set1.as_enumerable().non_common(set2.as_enumerable());
  210. parts.add_start("In set1 but not set2: ");
  211. parts.add_start(enumerable_int_to_string(diff));
  212. var result = parts.to_immutable_buffer()
  213. .aggregate<string>("", (acc, s) => acc + s);
  214. return new BufferedHttpResult.from_string(result);
  215. }
  216. }
  217. // Advanced operations
  218. class AdvancedHandler : Object, RouteHandler {
  219. public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
  220. var numbers = Wrap.array<int>({1, 2, 3, 4, 5});
  221. var parts = new Series<string>();
  222. // Take
  223. var taken = numbers.as_enumerable().take(3);
  224. parts.add_start("Take 3: ");
  225. parts.add_start(enumerable_int_to_string(taken));
  226. parts.add_start("\n");
  227. // Skip
  228. var skipped = numbers.as_enumerable().skip(2);
  229. parts.add_start("Skip 2: ");
  230. parts.add_start(enumerable_int_to_string(skipped));
  231. parts.add_start("\n");
  232. // Distinct
  233. var with_dupes = Wrap.array<int>({1, 2, 2, 3, 3, 3, 4});
  234. var distinct = with_dupes.as_enumerable().distinct();
  235. parts.add_start("Distinct from {1,2,2,3,3,3,4}: ");
  236. parts.add_start(enumerable_int_to_string(distinct));
  237. parts.add_start("\n");
  238. // Reverse
  239. var reversed = numbers.as_enumerable().reverse();
  240. parts.add_start("Reversed: ");
  241. parts.add_start(enumerable_int_to_string(reversed));
  242. var result = parts.to_immutable_buffer()
  243. .aggregate<string>("", (acc, s) => acc + s);
  244. return new BufferedHttpResult.from_string(result);
  245. }
  246. }
  247. void main() {
  248. var router = new Router();
  249. var server = new Server(8087, router);
  250. // Register routes
  251. router.get("/", new RootHandler());
  252. router.get("/filter", new FilterHandler());
  253. router.get("/map", new MapHandler());
  254. router.get("/group-by", new GroupByHandler());
  255. router.get("/aggregate", new AggregateHandler());
  256. router.get("/sort", new SortHandler());
  257. router.get("/set-operations", new SetOperationsHandler());
  258. router.get("/advanced", new AdvancedHandler());
  259. print("Enumerable Operations Demo Server running on port 8087\n");
  260. print("Try these endpoints:\n");
  261. print(" - http://localhost:8087/\n");
  262. print(" - http://localhost:8087/filter\n");
  263. print(" - http://localhost:8087/map\n");
  264. print(" - http://localhost:8087/group-by\n");
  265. print(" - http://localhost:8087/aggregate\n");
  266. print(" - http://localhost:8087/sort\n");
  267. print(" - http://localhost:8087/set-operations\n");
  268. print(" - http://localhost:8087/advanced\n");
  269. server.run();
  270. }
  271. // Helper functions
  272. string enumerable_int_to_string(Enumerable<int> enumerable) {
  273. return enumerable.to_immutable_buffer()
  274. .aggregate<string>("[", (acc, n) => {
  275. if (acc == "[") return acc + n.to_string();
  276. return acc + ", " + n.to_string();
  277. }) + "]";
  278. }
  279. string enumerable_string_to_string(Enumerable<string> enumerable) {
  280. return enumerable.to_immutable_buffer()
  281. .aggregate<string>("[", (acc, s) => {
  282. if (acc == "[") return acc + "\"" + s + "\"";
  283. return acc + ", \"" + s + "\"";
  284. }) + "]";
  285. }