{"id":32192010,"url":"https://github.com/edw/clj-lens","last_synced_at":"2025-10-22T01:56:03.476Z","repository":{"id":62432565,"uuid":"84322142","full_name":"edw/clj-lens","owner":"edw","description":"Nested data structure querying and updating","archived":false,"fork":false,"pushed_at":"2017-03-10T19:48:57.000Z","size":25,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-05T10:32:47.047Z","etag":null,"topics":["clojure","data-structures","datastructures"],"latest_commit_sha":null,"homepage":"","language":"Clojure","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/edw.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}},"created_at":"2017-03-08T13:16:48.000Z","updated_at":"2020-02-02T09:34:02.000Z","dependencies_parsed_at":"2022-11-01T20:47:05.425Z","dependency_job_id":null,"html_url":"https://github.com/edw/clj-lens","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/edw/clj-lens","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edw%2Fclj-lens","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edw%2Fclj-lens/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edw%2Fclj-lens/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edw%2Fclj-lens/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/edw","download_url":"https://codeload.github.com/edw/clj-lens/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edw%2Fclj-lens/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280365588,"owners_count":26318385,"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","status":"online","status_checked_at":"2025-10-21T02:00:06.614Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["clojure","data-structures","datastructures"],"created_at":"2025-10-22T01:56:01.121Z","updated_at":"2025-10-22T01:56:03.471Z","avatar_url":"https://github.com/edw.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Clj-lens: Nested data structure querying and updating\n\nHave you ever wanted to update a map in an array in a map? Do you ever\nwant to extract several values out of a similar data structure? Either\nsituation is a pain. And it's ugly, nesting all of those access and\nupdate functions into a pile a deeply-indented code. Clj-lens aspires\nto help you solve these problems in an Clojure-idiomatic way.\n\nObligatory incantation to keep the nannies at bay: Updating and even\naccessing deeply nested data may be a bad code smell. It may also\nrepresent an anti-pattern. Let's all write beautiful code, people.\n\n## Installation\n\nArtifacts are published on [Clojars][1]. \n\n![latest version][2]\n\n## Overview\n\nClj-lens allows the retrieval and updating of data structures through\npath specifications that allow maps, vectors, sets, and conceivably\nany type of compound data structures.\n\nClj-lens defines a protocol `AFocusable` containing two methods: `get`\nand `update*`. The `update*` method should not be called directly but\nthrough the `update` function, which allows multiple updates to be\napplied to a data structure. The `get-many` function can be used to\nretrieve a sequence of values based on zero or more path\nspecifications. Finally, a `let` macro is defined that allows you to\ndirectly bind values to names.\n\nLooking at the defined names described above, it should be pretty\nclear that you should not `:refer` to them but should instead require\nthe `clj-lens.core` namespace using a convenient name such as `lens`.\n\nLooking at the examples should make all or this transparently\nclear. If not, please complain to me by opening a Github issue.\n\n## Note on updating sets\n\nIf a set member is updated, the return value of the update function is\nexamined. If it is truthy, the returned value is conj'd unto the\nset--after the value associated with the path specification element\nvalue is disj'd from the set. If the returned value is equal to the\npath specification element value, the original set is changed. If the\nreturned value is not truthy, the path specification element value is\ndisj'd from the set.\n\n## Examples\n\n```clojure\n\n(require '[clj-lens.core :as lens])\n\n(def m {:a 0, :b 1, :c [41 \"Foocar\"]})\n(def n {:r (range 10)})\n\n(lens/get m [:c 1]) ;; =\u003e \"Foocar\"\n(lens/get 42 [])    ;; =\u003e 42\n\n(lens/update m [:c 1 3] (fn [_] \\b)) ;; =\u003e {:a 0, :b 1, :c [41 \"Foobar\"]}\n(lens/update 0 [] #(+ % 42))         ;; =\u003e 42\n\n(lens/update n [:r] #(map (partial * 10) %))\n;; =\u003e {:r (0 10 20 30 40 50 60 70 80 90)} ; Still lazy\n\n(lens/get-many m [:a] [:c 1 0])    ;; =\u003e (0 \\F)\n(lens/get-many m [:a] [:c 1 0] []) ;; =\u003e (0 \\F {:a 0, :b 1, :c [41 \"Foocar\"]})\n\n(lens/let m\n    [p [:a]\n     q [:c 1 0]\n     :as r]\n  (list p q r))\n;; =\u003e (0 \\F {:a 0, :b 1, :c [41 \"Foocar\"]}) ; Very similar to above\n\n(lens/let {:a [0 1 2]}\n    [[zero one two] [:a]]\n  (list zero one two))\n;; =\u003e (0 1 2)\n\n(lens/update\n m\n [:a] dec\n [:b] inc\n [:d :i] (fn [_] #{:clubs :diamonds :hearts :spades}))\n;; =\u003e\n;;\n;; {:a -1,\n;;  :b 2,\n;;  :c [41 \"Foocar\"],\n;;  :d {:i #{:spades :diamonds :clubs :hearts}}}\n\n```\n\n[1]: https://clojars.org/edw/clj-lens\n[2]: https://clojars.org/edw/clj-lens/latest-version.svg\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedw%2Fclj-lens","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fedw%2Fclj-lens","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedw%2Fclj-lens/lists"}