{"id":30507861,"url":"https://github.com/edjcase/motoko_collections","last_synced_at":"2026-02-13T05:46:13.516Z","repository":{"id":308634019,"uuid":"1033457122","full_name":"edjCase/motoko_collections","owner":"edjCase","description":"A motoko implementation of a simple dynamic array (fork of Buffer.Buffer from deprecated base library)","archived":false,"fork":false,"pushed_at":"2025-09-06T21:31:53.000Z","size":109,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-12T01:07:17.595Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Motoko","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/edjCase.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-06T21:02:46.000Z","updated_at":"2025-09-06T21:31:56.000Z","dependencies_parsed_at":"2025-09-12T00:18:59.999Z","dependency_job_id":"51b36906-dfea-435b-8fdf-ee0ef3d3abcc","html_url":"https://github.com/edjCase/motoko_collections","commit_stats":null,"previous_names":["edjcase/motoko_xtended_collections"],"tags_count":0,"template":false,"template_full_name":"edjCase/motoko-library-template","purl":"pkg:github/edjCase/motoko_collections","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edjCase%2Fmotoko_collections","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edjCase%2Fmotoko_collections/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edjCase%2Fmotoko_collections/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edjCase%2Fmotoko_collections/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/edjCase","download_url":"https://codeload.github.com/edjCase/motoko_collections/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edjCase%2Fmotoko_collections/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29397197,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-13T04:26:15.637Z","status":"ssl_error","status_checked_at":"2026-02-13T04:16:29.732Z","response_time":78,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2025-08-25T20:40:48.881Z","updated_at":"2026-02-13T05:46:13.503Z","avatar_url":"https://github.com/edjCase.png","language":"Motoko","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Motoko Extended Collections Library\n\n[![MOPS](https://img.shields.io/badge/MOPS-xtended--collections-blue)](https://mops.one/xtended-collections)\n[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://github.com/edjCase/motoko_xtended_collections/blob/main/LICENSE)\n\nA Motoko library that provides extended collections including `DynamicArray` (fork of deprecated `mo:base/Buffer`) and `StableDynamicArray` (fork of `canscale/StableBuffer`)\n\n## MOPS\n\n```bash\nmops add xtended-collections\n```\n\nTo set up MOPS package manager, follow the instructions from the [MOPS Site](https://mops.one)\n\n## DynamicArray Module\n\nThe `DynamicArray\u003cX\u003e` class provides a mutable list of elements of type `X` with automatic resizing capabilities. It's comparable to `ArrayList` or `Vector` in other programming languages.\n\n### Example Usage\n\n```motoko\nimport DynamicArray \"mo:xtended-collections/DynamicArray\";\nimport Nat \"mo:core/Nat\";\n\n// Create a new dynamic array\nlet dynamicArray = DynamicArray.DynamicArray\u003cNat\u003e(3);\n\n// Add elements\ndynamicArray.add(1);\ndynamicArray.add(2);\ndynamicArray.add(3);\n\n// Access elements\nlet first = dynamicArray.get(0); // =\u003e 1\nlet size = dynamicArray.size(); // =\u003e 3\n\n// Transform elements\nlet doubled = DynamicArray.map(dynamicArray, func(x) { x * 2 });\n\n// Convert to array\nlet array = DynamicArray.toArray(dynamicArray); // =\u003e [1, 2, 3]\n\n// Sort elements\ndynamicArray.sort(Nat.compare);\n\n// Find elements\nlet index = DynamicArray.indexOf(2, dynamicArray, Nat.equal); // =\u003e ?1\n```\n\n### Constructor\n\n```motoko\nlet dynamicArray = DynamicArray.DynamicArray\u003cNat\u003e(8); // Initial capacity of 8\n```\n\nThe constructor takes an initial capacity parameter that determines the size of the underlying array. When capacity is exceeded, the array grows by a factor of 1.5. When the size drops below 1/4 of capacity, it shrinks by a factor of 2.\n\n### Core Operations\n\n#### Basic Operations\n\n-   `add(element)`: Add element to the end\n-   `get(index)`: Get element at index (traps if out of bounds)\n-   `getOpt(index)`: Get element at index as option\n-   `put(index, element)`: Replace element at index\n-   `remove(index)`: Remove element at index\n-   `removeLast()`: Remove and return last element\n-   `size()`: Get current number of elements\n-   `capacity()`: Get current capacity\n\n#### Bulk Operations\n\n-   `append(dynamicArray2)`: Add all elements from another DynamicArray\n-   `insert(index, element)`: Insert element at specific index\n-   `insertDynamicArray(index, dynamicArray2)`: Insert another DynamicArray at index\n-   `clear()`: Remove all elements\n-   `reserve(capacity)`: Set minimum capacity\n\n#### Search and Query\n\n-   `contains(element, equal)`: Check if element exists\n-   `indexOf(element, equal)`: Find first index of element\n-   `lastIndexOf(element, equal)`: Find last index of element\n-   `binarySearch(element, compare)`: Binary search in sorted array\n-   `isEmpty()`: Check if array is empty\n\n#### Transformation and Iteration\n\n-   `map(f)`: Transform elements with function\n-   `mapEntries(f)`: Transform elements with index\n-   `mapFilter(f)`: Transform and filter elements\n-   `mapResult(f)`: Transform with error handling\n-   `filter(predicate)`: Keep elements matching predicate\n-   `sort(compare)`: Sort elements in-place\n-   `reverse()`: Reverse element order\n\n#### Conversion\n\n-   `toArray()`: Convert to immutable array\n-   `toVarArray()`: Convert to mutable array\n-   `vals()`: Get iterator over elements\n-   `buffer()`: Get Buffer interface\n\n### Advanced Operations\n\n#### Array Manipulation\n\n-   `subDynamicArray(start, length)`: Extract sub-array\n-   `prefix(length)`: Get first n elements\n-   `suffix(length)`: Get last n elements\n-   `split(index)`: Split into two arrays at index\n\n#### Functional Operations\n\n-   `foldLeft(base, combine)`: Reduce from left\n-   `foldRight(base, combine)`: Reduce from right\n-   `chain(k)`: Monadic bind operation\n-   `partition(predicate)`: Split based on predicate\n-   `zip(dynamicArray2)`: Combine with another array\n-   `zipWith(dynamicArray2, f)`: Combine with transformation\n\n#### Grouping and Chunking\n\n-   `chunk(size)`: Break into fixed-size chunks\n-   `groupBy(equal)`: Group adjacent equal elements\n-   `flatten()`: Flatten array of arrays\n-   `takeWhile(predicate)`: Take elements while condition holds\n-   `dropWhile(predicate)`: Skip elements while condition holds\n\n#### Comparison and Analysis\n\n-   `equal(dynamicArray2, equal)`: Compare arrays for equality\n-   `compare(dynamicArray2, compare)`: Lexicographic comparison\n-   `max(compare)`: Find maximum element\n-   `min(compare)`: Find minimum element\n-   `forAll(predicate)`: Check if all elements satisfy condition\n-   `forSome(predicate)`: Check if any element satisfies condition\n-   `forNone(predicate)`: Check if no element satisfies condition\n\n### Static Functions\n\n```motoko\n// Utility functions\npublic func isEmpty\u003cX\u003e(dynamicArray : DynamicArray\u003cX\u003e) : Bool\npublic func contains\u003cX\u003e(dynamicArray : DynamicArray\u003cX\u003e, element : X, equal : (X, X) -\u003e Bool) : Bool\npublic func clone\u003cX\u003e(dynamicArray : DynamicArray\u003cX\u003e) : DynamicArray\u003cX\u003e\n\n// Conversion functions\npublic func fromArray\u003cX\u003e(array : [X]) : DynamicArray\u003cX\u003e\npublic func fromVarArray\u003cX\u003e(array : [var X]) : DynamicArray\u003cX\u003e\npublic func fromIter\u003cX\u003e(iter : { next : () -\u003e ?X }) : DynamicArray\u003cX\u003e\npublic func toArray\u003cX\u003e(dynamicArray : DynamicArray\u003cX\u003e) : [X]\npublic func toVarArray\u003cX\u003e(dynamicArray : DynamicArray\u003cX\u003e) : [var X]\n\n// Analysis functions\npublic func max\u003cX\u003e(dynamicArray : DynamicArray\u003cX\u003e, compare : (X, X) -\u003e Order) : ?X\npublic func min\u003cX\u003e(dynamicArray : DynamicArray\u003cX\u003e, compare : (X, X) -\u003e Order) : ?X\npublic func equal\u003cX\u003e(dynamicArray1 : DynamicArray\u003cX\u003e, dynamicArray2 : DynamicArray\u003cX\u003e, equal : (X, X) -\u003e Bool) : Bool\npublic func compare\u003cX\u003e(dynamicArray1 : DynamicArray\u003cX\u003e, dynamicArray2 : DynamicArray\u003cX\u003e, compare : (X, X) -\u003e Order.Order) : Order.Order\n\n// Text and hashing\npublic func toText\u003cX\u003e(dynamicArray : DynamicArray\u003cX\u003e, toText : X -\u003e Text) : Text\npublic func hash\u003cX\u003e(dynamicArray : DynamicArray\u003cX\u003e, hash : X -\u003e Nat32) : Nat32\n\n// Advanced operations\npublic func merge\u003cX\u003e(dynamicArray1 : DynamicArray\u003cX\u003e, dynamicArray2 : DynamicArray\u003cX\u003e, compare : (X, X) -\u003e Order) : DynamicArray\u003cX\u003e\npublic func removeDuplicates\u003cX\u003e(dynamicArray : DynamicArray\u003cX\u003e, compare : (X, X) -\u003e Order)\n```\n\n### Performance Characteristics\n\nMost operations have the following complexity:\n\n| Operation    | Time Complexity                                  | Space Complexity |\n| ------------ | ------------------------------------------------ | ---------------- |\n| `add`        | O(1) amortized, O(n) worst case                  | O(1) amortized   |\n| `get/put`    | O(1)                                             | O(1)             |\n| `remove`     | O(n)                                             | O(1) amortized   |\n| `append`     | O(m) amortized where m is size of appended array | O(1) amortized   |\n| `sort`       | O(n log n)                                       | O(n)             |\n| `map/filter` | O(n)                                             | O(n)             |\n\n### Notes\n\n-   Operations like `add` are amortized O(1) but can take O(n) in the worst case due to resizing\n-   For large arrays, worst-case operations may exceed cycle limits in some environments\n-   The array maintains the invariant that `capacity \u003e= size`\n-   Recommended for storing data in stable variables by converting to arrays first\n\n## StableDynamicArray Module\n\nThe `StableDynamicArray\u003cX\u003e` module provides persistent, stable dynamic arrays that maintain their state across canister upgrades. Unlike the class-based `DynamicArray`, this is a module with functions that operate on a stable data structure.\n\n### Key Features\n\n-   **Upgrade-safe**: Maintains state across canister upgrades when declared as `stable`\n-   **Functional interface**: Uses module functions instead of class methods\n-   **Same performance characteristics**: Similar O(1) amortized operations as DynamicArray\n-   **Compatible API**: Most operations mirror the DynamicArray interface\n\n### Example Usage\n\n```motoko\nimport StableDynamicArray \"mo:xtended-collections/StableDynamicArray\";\n\n// Declare as stable to persist across upgrades\nstable let stableArray = StableDynamicArray.init\u003cNat\u003e();\n\n// Add elements\nStableDynamicArray.add(stableArray, 42);\nStableDynamicArray.add(stableArray, 100);\n\n// Access elements\nlet size = StableDynamicArray.size(stableArray);\nlet firstElement = StableDynamicArray.get(stableArray, 0);\n```\n\nSee the module documentation for the complete API reference.\n\n## Attribution\n\n**DynamicArray Module**: This module contains code originally from the [DFINITY Motoko Base Library](https://github.com/dfinity/motoko-base), specifically the `Buffer` module. The original code is licensed under Apache License 2.0.\n\n-   Original Copyright: DFINITY Foundation\n-   Original Repository: https://github.com/dfinity/motoko-base\n-   Original License: Apache License 2.0\n\n**StableDynamicArray Module**: This module contains code originally from the [canscale StableBuffer](https://github.com/canscale/StableBuffer) repository. The original code is licensed under Apache License 2.0.\n\n-   Original Copyright: canscale organization and contributors\n-   Original Repository: https://github.com/canscale/StableBuffer\n-   Original License: Apache License 2.0\n\nAll other components in this library are original work unless otherwise noted.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedjcase%2Fmotoko_collections","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fedjcase%2Fmotoko_collections","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedjcase%2Fmotoko_collections/lists"}