{"id":13879394,"url":"https://github.com/panorama-ed/scan_left","last_synced_at":"2025-05-12T16:14:46.450Z","repository":{"id":43478108,"uuid":"261464416","full_name":"panorama-ed/scan_left","owner":"panorama-ed","description":"A tiny Ruby gem to provide the 'scan_left' operation on any Ruby Enumerable.","archived":false,"fork":false,"pushed_at":"2025-03-24T04:54:02.000Z","size":224,"stargazers_count":13,"open_issues_count":1,"forks_count":0,"subscribers_count":28,"default_branch":"main","last_synced_at":"2025-05-02T06:18:36.286Z","etag":null,"topics":["enumerator","fp","ruby"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/panorama-ed.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-05T12:40:13.000Z","updated_at":"2025-03-24T04:53:12.000Z","dependencies_parsed_at":"2023-11-06T06:25:11.882Z","dependency_job_id":"efae039f-6be7-4ddf-9034-e8ca75274672","html_url":"https://github.com/panorama-ed/scan_left","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panorama-ed%2Fscan_left","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panorama-ed%2Fscan_left/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panorama-ed%2Fscan_left/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panorama-ed%2Fscan_left/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/panorama-ed","download_url":"https://codeload.github.com/panorama-ed/scan_left/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253774581,"owners_count":21962199,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["enumerator","fp","ruby"],"created_at":"2024-08-06T08:02:19.482Z","updated_at":"2025-05-12T16:14:46.424Z","avatar_url":"https://github.com/panorama-ed.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# scan_left\n[![Tests](https://github.com/panorama-ed/scan_left/workflows/Tests/badge.svg)](https://github.com/panorama-ed/scan_left/actions?query=workflow%3ATests)\n\n[![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://rubydoc.info/github/panorama-ed/scan_left)\n[![Docs Coverage](http://inch-ci.org/github/panorama-ed/scan_left.png)](http://inch-ci.org/github/panorama-ed/scan_left)\n\n[![Gem Version](https://img.shields.io/gem/v/scan_left.svg)](https://rubygems.org/gems/scan_left)\n[![Gem Downloads](https://img.shields.io/gem/dt/scan_left.svg)](https://rubygems.org/gems/scan_left)\n\nA tiny Ruby gem to provide the `#scan_left` operation on any Ruby\n`Enumerable`.\n\n## What does it do?\n\nImagine a series of numbers which you want to *sum*. You accomplish\nthis by processing all elements, adding each to the previous sum,\nreturning the final result.\n\nNow imagine that, rather than just the final sum at the end of the\nseries, you want *a series* of the partial sums after processing each\nelement. This is called a [\"Prefix\nSum\"](https://en.wikipedia.org/wiki/Prefix_sum).\n\nIn functional programming (FP), the *sum* is generalized as the *fold*\noperation, in which an initial state and a binary operation are\ncombined to \"fold\" a series of values into a single result. The\nclosely related *prefix sum*, which produces a series of intermediate\nresults, is generalized as the *scan* operation. Adding \"left\" to\nthese operation names indicates that calculation is to proceed\nleft-to-right.\n\n## Compare / Contrast with #inject\n\nRuby's standard library operation `Enumerable#inject` implements the\nFP fold operation. It also implements the simpler reduce operation,\nwhich is a fold whose initial state is the first element of the\nseries.\n\nThe key differences between `#inject` and `#scan_left` are:\n\n  1. **Incremental results**: `#scan_left` returns a series of results\n     after processing each element of the input series. `#inject`\n     returns a single value, which equals the final result in the\n     series returned by `#scan_left`.\n\n  2. **Laziness**: `#scan_left` can preserve the laziness of the input\n     series.  As each incremental result is read from the output\n     series, the actual calculation is lazily performed against the\n     input. `#inject` cannot be a lazy operation in general, as its\n     single result reflects a calculation across every element of the\n     input series.\n\n## Examples\n\n```ruby\nrequire \"scan_left\"\n\n# For comparison, results from #inject are shown as well:\n\nScanLeft.new([]).scan_left(0) { |s, x| s + x } == [0]\n[].inject(0) { |s, x| s + x }                  == 0\n\nScanLeft.new([1]).scan_left(0) { |s, x| s + x } == [0, 1]\n[1].inject(0) { |s, x| s + x }                  == 1\n\nScanLeft.new([1, 2, 3]).scan_left(0) { |s, x| s + x } == [0, 1, 3, 6]\n[1, 2, 3].inject(0) { |s, x| s + x }                  == 6\n\n# OPTIONAL: To avoid explicitly using the `ScanLeft` class, you may\n# choose to use the provided refinement on Enumerable. \n#\n# This refinement adds a `#scan_left` method directly to Enumerable \n# for a more concise syntax.\n\nusing EnumerableWithScanleft\n\n[].scan_left(0) { |s, x| s + x }        =\u003e [0]\n[1].scan_left(0) { |s, x| s + x }       =\u003e [0, 1]\n[1, 2, 3].scan_left(0) { |s, x| s + x } =\u003e [0, 1, 3, 6]\n```\n\n## Further Reading\n\n  * https://en.wikipedia.org/wiki/Fold_(higher-order_function)\n  * https://en.wikipedia.org/wiki/Prefix_sum#Scan_higher_order_function\n  * http://alvinalexander.com/scala/how-to-walk-scala-collections-reduceleft-foldright-cookbook#scanleft-and-scanright\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpanorama-ed%2Fscan_left","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpanorama-ed%2Fscan_left","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpanorama-ed%2Fscan_left/lists"}