using Astralis; using Invercargill; using Invercargill.DataStructures; /** * EnumerableOperations Example * * Demonstrates various LINQ-like operations available in Invercargill Enumerable. * This example shows filtering, mapping, grouping, and aggregation operations. */ // Root handler class RootEndpoint : Object, Endpoint { public string route { get { return "/"; } } public Method[] methods { owned get { return { Method.GET }; } } public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error { return new HttpStringResult("""Enumerable Operations Demo This example demonstrates various LINQ-like operations available in Invercargill Enumerable: Endpoints: GET /filter - Filtering examples GET /map - Mapping/Projection examples GET /group-by - Grouping examples GET /aggregate - Aggregation examples GET /sort - Sorting examples GET /set-operations - Set operations (union, intersection, etc.) GET /advanced - Advanced operations (zip, partition, etc.) """); } } // Filtering examples class FilterEndpoint : Object, Endpoint { public string route { get { return "/filter"; } } public Method[] methods { owned get { return { Method.GET }; } } public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error { var numbers = Wrap.array({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); var parts = new Series(); parts.add_start("Original: "); parts.add_start(enumerable_int_to_string(numbers.as_enumerable())); parts.add_start("\n\n"); // Filter even numbers var even = numbers.as_enumerable() .where(n => n % 2 == 0); parts.add_start("Even numbers: "); parts.add_start(enumerable_int_to_string(even)); parts.add_start("\n"); // Filter odd numbers var odd = numbers.as_enumerable() .where(n => n % 2 != 0); parts.add_start("Odd numbers: "); parts.add_start(enumerable_int_to_string(odd)); parts.add_start("\n"); // Filter numbers greater than 5 var greater_than_5 = numbers.as_enumerable() .where(n => n > 5); parts.add_start("Greater than 5: "); parts.add_start(enumerable_int_to_string(greater_than_5)); parts.add_start("\n\n"); // Chained filters var filtered = numbers.as_enumerable() .where(n => n > 3) .where(n => n < 8); parts.add_start("Between 3 and 8: "); parts.add_start(enumerable_int_to_string(filtered)); var result = parts.to_immutable_buffer() .aggregate("", (acc, s) => acc + s); return new HttpStringResult(result); } } // Mapping/Projection examples class MapEndpoint : Object, Endpoint { public string route { get { return "/map"; } } public Method[] methods { owned get { return { Method.GET }; } } public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error { var numbers = Wrap.array({1, 2, 3, 4, 5}); var parts = new Series(); parts.add_start("Original: "); parts.add_start(enumerable_int_to_string(numbers.as_enumerable())); parts.add_start("\n\n"); // Square each number var squared = numbers.as_enumerable() .select(n => n * n); parts.add_start("Squared: "); parts.add_start(enumerable_int_to_string(squared)); parts.add_start("\n"); // Double each number var doubled = numbers.as_enumerable() .select(n => n * 2); parts.add_start("Doubled: "); parts.add_start(enumerable_int_to_string(doubled)); parts.add_start("\n"); // Convert to string var as_strings = numbers.as_enumerable() .select(n => n.to_string()); parts.add_start("As strings: "); parts.add_start(enumerable_string_to_string(as_strings)); parts.add_start("\n\n"); // With index var with_index = numbers.as_enumerable() .with_positions() .select(pair => @"$(pair.item) at index $(pair.position)"); parts.add_start("With index: "); parts.add_start(enumerable_string_to_string(with_index)); var result = parts.to_immutable_buffer() .aggregate("", (acc, s) => acc + s); return new HttpStringResult(result); } } // Grouping examples class GroupByEndpoint : Object, Endpoint { public string route { get { return "/group-by"; } } public Method[] methods { owned get { return { Method.GET }; } } public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error { var words = Wrap.array({ "apple", "banana", "cherry", "apricot", "blueberry", "blackberry", "coconut" }); var parts = new Series(); parts.add_start("Words: "); parts.add_start(enumerable_string_to_string(words.as_enumerable())); parts.add_start("\n\n"); // Group by first letter var grouped = words.as_enumerable() .group_by(w => w.get_char(0).to_string()); parts.add_start("Grouped by first letter:\n"); grouped.iterate((grouping) => { parts.add_start(@" $(grouping.key): "); parts.add_start(enumerable_string_to_string(grouping.to_immutable_buffer())); parts.add_start("\n"); }); var result = parts.to_immutable_buffer() .aggregate("", (acc, s) => acc + s); return new HttpStringResult(result); } } // Aggregation examples class AggregateEndpoint : Object, Endpoint { public string route { get { return "/aggregate"; } } public Method[] methods { owned get { return { Method.GET }; } } public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error { var numbers = Wrap.array({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); var parts = new Series(); parts.add_start("Numbers: "); parts.add_start(enumerable_int_to_string(numbers.as_enumerable())); parts.add_start("\n\n"); // Count var count = numbers.as_enumerable().count(); parts.add_start(@"Count: $count\n"); // Sum using aggregate var sum = numbers.as_enumerable() .aggregate(0, (acc, n) => acc + n); parts.add_start(@"Sum: $sum\n"); // Average var avg = (double)sum / count; parts.add_start(@"Average: $avg\n"); // Min var min = numbers.as_enumerable().min(n => n); parts.add_start(@"Min: $min\n"); // Max var max = numbers.as_enumerable().max(n => n); parts.add_start(@"Max: $max\n"); // First var first = numbers.as_enumerable().first(); parts.add_start(@"First: $first\n"); // Last var last = numbers.as_enumerable().last(); parts.add_start(@"Last: $last\n"); var result = parts.to_immutable_buffer() .aggregate("", (acc, s) => acc + s); return new HttpStringResult(result); } } // Sorting examples class SortEndpoint : Object, Endpoint { public string route { get { return "/sort"; } } public Method[] methods { owned get { return { Method.GET }; } } public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error { var numbers = Wrap.array({5, 2, 8, 1, 9, 3, 7, 4, 6, 10}); var parts = new Series(); parts.add_start("Original: "); parts.add_start(enumerable_int_to_string(numbers.as_enumerable())); parts.add_start("\n\n"); // Sort ascending var sorted_asc = numbers.as_enumerable() .order_by(n => n); parts.add_start("Ascending: "); parts.add_start(enumerable_int_to_string(sorted_asc)); parts.add_start("\n"); // Sort descending var sorted_desc = numbers.as_enumerable() .order_by_descending(n => n); parts.add_start("Descending: "); parts.add_start(enumerable_int_to_string(sorted_desc)); var result = parts.to_immutable_buffer() .aggregate("", (acc, s) => acc + s); return new HttpStringResult(result); } } // Set operations class SetOperationsEndpoint : Object, Endpoint { public string route { get { return "/set-operations"; } } public Method[] methods { owned get { return { Method.GET }; } } public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error { var set1 = Wrap.array({1, 2, 3, 4, 5}); var set2 = Wrap.array({4, 5, 6, 7, 8}); var parts = new Series(); parts.add_start("Set 1: "); parts.add_start(enumerable_int_to_string(set1.as_enumerable())); parts.add_start("\n"); parts.add_start("Set 2: "); parts.add_start(enumerable_int_to_string(set2.as_enumerable())); parts.add_start("\n\n"); // Union (concat) var union = set1.as_enumerable().concat(set2.as_enumerable()); parts.add_start("Union: "); parts.add_start(enumerable_int_to_string(union)); parts.add_start("\n"); // Common (intersection) var common = set1.as_enumerable().common(set2.as_enumerable()); parts.add_start("Common: "); parts.add_start(enumerable_int_to_string(common)); parts.add_start("\n"); // Non-common (difference) var diff = set1.as_enumerable().non_common(set2.as_enumerable()); parts.add_start("In set1 but not set2: "); parts.add_start(enumerable_int_to_string(diff)); var result = parts.to_immutable_buffer() .aggregate("", (acc, s) => acc + s); return new HttpStringResult(result); } } // Advanced operations class AdvancedEndpoint : Object, Endpoint { public string route { get { return "/advanced"; } } public Method[] methods { owned get { return { Method.GET }; } } public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error { var numbers = Wrap.array({1, 2, 3, 4, 5}); var parts = new Series(); // Take var taken = numbers.as_enumerable().take(3); parts.add_start("Take 3: "); parts.add_start(enumerable_int_to_string(taken)); parts.add_start("\n"); // Skip var skipped = numbers.as_enumerable().skip(2); parts.add_start("Skip 2: "); parts.add_start(enumerable_int_to_string(skipped)); parts.add_start("\n"); // Distinct var with_dupes = Wrap.array({1, 2, 2, 3, 3, 3, 4}); var distinct = with_dupes.as_enumerable().distinct(); parts.add_start("Distinct from {1,2,2,3,3,3,4}: "); parts.add_start(enumerable_int_to_string(distinct)); parts.add_start("\n"); // Reverse var reversed = numbers.as_enumerable().reverse(); parts.add_start("Reversed: "); parts.add_start(enumerable_int_to_string(reversed)); var result = parts.to_immutable_buffer() .aggregate("", (acc, s) => acc + s); return new HttpStringResult(result); } } void main() { var router = new EndpointRouter() .add_endpoint(new RootEndpoint()) .add_endpoint(new FilterEndpoint()) .add_endpoint(new MapEndpoint()) .add_endpoint(new GroupByEndpoint()) .add_endpoint(new AggregateEndpoint()) .add_endpoint(new SortEndpoint()) .add_endpoint(new SetOperationsEndpoint()) .add_endpoint(new AdvancedEndpoint()); var pipeline = new Pipeline() .add_component(router); var server = new Server(8087, pipeline); print("Enumerable Operations Demo Server running on port 8087\n"); print("Try these endpoints:\n"); print(" - http://localhost:8087/\n"); print(" - http://localhost:8087/filter\n"); print(" - http://localhost:8087/map\n"); print(" - http://localhost:8087/group-by\n"); print(" - http://localhost:8087/aggregate\n"); print(" - http://localhost:8087/sort\n"); print(" - http://localhost:8087/set-operations\n"); print(" - http://localhost:8087/advanced\n"); server.run(); } // Helper functions string enumerable_int_to_string(Enumerable enumerable) { return enumerable.to_immutable_buffer() .aggregate("[", (acc, n) => { if (acc == "[") return acc + n.to_string(); return acc + ", " + n.to_string(); }) + "]"; } string enumerable_string_to_string(Enumerable enumerable) { return enumerable.to_immutable_buffer() .aggregate("[", (acc, s) => { if (acc == "[") return acc + "\"" + s + "\""; return acc + ", \"" + s + "\""; }) + "]"; }