{"id":"pineappleblaster/linq-luau","name":"linq-luau","scope":"pineappleblaster","platform":"roblox","description":"A typed, lazy, chainable query API for Luau collections.","version":"0.4.1","latest":"0.4.1","versions":["0.4.1"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"975aded12732116b94d536f18d57d555115d931bf3cb7eb31a329d6d57ff0328","likes":0,"downloads":0,"install":"forest install pineappleblaster/linq-luau","url":"https://forest.dev/p/roblox/pineappleblaster/linq-luau","files":"https://api.forest.dev/ai/package/roblox/pineappleblaster/linq-luau/files","readme":"# LINQ\r\n\r\nA typed, lazy, chainable query API for Luau collections.\r\n\r\nLINQ provides a familiar way to filter, transform, group, sort, and aggregate arrays and dictionaries without repeatedly writing traversal logic.\r\n\r\n```lua\r\nlocal LINQ = require(Packages.LINQ)\r\n\r\nlocal result = LINQ(workspace:GetDescendants())\r\n\t:Where(function(instance)\r\n\t\treturn instance:IsA(\"BasePart\")\r\n\tend)\r\n\t:FirstOrNil()\r\n```\r\n\r\n## Features\r\n\r\n* Lazy query execution\r\n* Chainable, strongly typed API\r\n* Array and dictionary support\r\n* Short-circuiting terminals such as `First`, `Any`, and `All`\r\n* Streaming execution for most operators\r\n* Fused fast paths for common query shapes\r\n* Stable `OrderBy` / `ThenBy`\r\n* `Distinct` and `DistinctBy`\r\n* `SelectMany`\r\n* `GroupBy`\r\n* `Aggregate`, `Sum`, `Average`, `Min`, and `Max`\r\n\r\n## Installation\r\n\r\n```toml\r\n[dependencies]\r\nLINQ = \"pineappleblaster/linq-lua@0.4.1\"\r\n```\r\n\r\nThen require it from your Wally packages directory:\r\n\r\n```lua\r\nlocal LINQ = require(Packages.LINQ)\r\n```\r\n\r\n## Usage\r\n\r\n### Filtering\r\n\r\n```lua\r\nlocal enemies = LINQ(characters)\r\n\t:Where(function(character)\r\n\t\treturn character:GetAttribute(\"Team\") == \"Enemy\"\r\n\tend)\r\n\t:ToArray()\r\n```\r\n\r\n### Mapping\r\n\r\n```lua\r\nlocal names = LINQ(players)\r\n\t:Select(function(player)\r\n\t\treturn player.Name\r\n\tend)\r\n\t:ToArray()\r\n```\r\n\r\n### Finding a value\r\n\r\n```lua\r\nlocal part = LINQ(workspace:GetDescendants())\r\n\t:Where(function(instance)\r\n\t\treturn instance:IsA(\"BasePart\")\r\n\tend)\r\n\t:FirstOrNil()\r\n```\r\n\r\n### Sorting\r\n\r\n```lua\r\nlocal sorted = LINQ(players)\r\n\t:OrderBy(function(player)\r\n\t\treturn player.Level\r\n\tend, true)\r\n\t:ThenBy(function(player)\r\n\t\treturn player.Name\r\n\tend)\r\n\t:ToArray()\r\n```\r\n\r\n### Dictionaries\r\n\r\nDictionary sources are exposed as entries containing `Key` and `Value`.\r\n\r\n```lua\r\nlocal entries = LINQ({\r\n\tHealth = 100,\r\n\tSpeed = 16,\r\n\tDamage = 25,\r\n})\r\n\t:Where(function(entry)\r\n\t\treturn entry.Value >= 25\r\n\tend)\r\n\t:ToArray()\r\n```\r\n\r\n## API\r\n\r\n### Query operators\r\n\r\n```text\r\nWhere\r\nSelect\r\nSkip\r\nTake\r\nDistinct\r\nDistinctBy\r\nSelectMany\r\nOrderBy\r\nThenBy\r\nReverse\r\nConcat\r\n```\r\n\r\n### Terminal operators\r\n\r\n```text\r\nToArray\r\nToDictionary\r\nFirst\r\nFirstOrNil\r\nLast\r\nLastOrNil\r\nAny\r\nAll\r\nCount\r\nGroupBy\r\nAggregate\r\nMin\r\nMax\r\nSum\r\nAverage\r\n```\r\n\r\n## Execution Model\r\n\r\nQueries are deferred until a terminal operation is called.\r\n\r\nMost operators are compiled into a streaming pipeline:\r\n\r\n```text\r\nSource → Where → Select → Take → Terminal\r\n```\r\n\r\nValues move through the query one at a time without allocating an intermediate table for each stage.\r\n\r\nOperations such as `OrderBy` and `Reverse` require the complete upstream sequence and therefore act as buffering barriers:\r\n\r\n```text\r\nSource → Where → [OrderBy] → Select → Take\r\n```\r\n\r\nOnly the required portion of the pipeline is materialized; execution continues streaming afterward.\r\n\r\nThe pipeline also supports upstream cancellation, allowing operations such as `First`, `Any`, and `Take` to stop enumeration as soon as their result is known.\r\n\r\n## Notes\r\n\r\nQuery objects retain a reference to their original source table rather than copying it. Mutating the source before execution can therefore affect the query result.\r\n\r\nCallbacks should not return `nil` where the resulting value must be stored in an array.\r\n\r\n## License\r\n\r\nMIT\r\n","readmeTruncated":false}