{"id":19714399,"url":"https://github.com/peternaydenov/walk","last_synced_at":"2025-04-29T19:32:52.769Z","repository":{"id":57135897,"uuid":"466004599","full_name":"PeterNaydenov/walk","owner":"PeterNaydenov","description":"Deep copy with fine control during the process. Can be used also as a deep 'forEach'","archived":false,"fork":false,"pushed_at":"2025-04-28T07:11:28.000Z","size":191,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-28T08:25:42.236Z","etag":null,"topics":["callback","deep-copy","object-callback","property-callback"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/PeterNaydenov.png","metadata":{"files":{"readme":"README.md","changelog":"Changelog.md","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}},"created_at":"2022-03-04T06:11:17.000Z","updated_at":"2025-04-28T07:11:32.000Z","dependencies_parsed_at":"2024-04-21T16:09:18.117Z","dependency_job_id":"60f5e292-8756-4f16-a40f-d581c4a393dd","html_url":"https://github.com/PeterNaydenov/walk","commit_stats":{"total_commits":32,"total_committers":1,"mean_commits":32.0,"dds":0.0,"last_synced_commit":"af29aa9d8308d0609323933104776c94c20aa314"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeterNaydenov%2Fwalk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeterNaydenov%2Fwalk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeterNaydenov%2Fwalk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeterNaydenov%2Fwalk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PeterNaydenov","download_url":"https://codeload.github.com/PeterNaydenov/walk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251569648,"owners_count":21610596,"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":["callback","deep-copy","object-callback","property-callback"],"created_at":"2024-11-11T22:31:29.156Z","updated_at":"2025-04-29T19:32:52.762Z","avatar_url":"https://github.com/PeterNaydenov.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Walk (@peter.naydenov/walk) ( Version 5.x.x )\n\n![version](https://img.shields.io/github/package-json/v/peterNaydenov/walk)\n![license](https://img.shields.io/github/license/peterNaydenov/walk)\n![npm](https://img.shields.io/npm/dt/%40peter.naydenov/walk)\n![GitHub issues](https://img.shields.io/github/issues/peterNaydenov/walk)\n![GitHub top language](https://img.shields.io/github/languages/top/peterNaydenov/walk)\n![npm package minimized gzipped size (select exports)](https://img.shields.io/bundlejs/size/%40peter.naydenov%2Fwalk)\n\n\n\n\nCreates an immutable copies of javascript data structures(objects, arrays or mixed). Executes callback functions on every object property(object-callback) and every primitive property(key-callback). Callbacks can modify result-object during the walk process. Mask, filter or substitute values during the copy process. \n\n```js\nconst result = walk ({\n                            data             // (required) Any JS data structure;\n                          , objectCallback   // (optional) Function executed on each object property;\n                          , keyCallback      // (optional) Function executed on each primitive property;\n                    })\n// Result will become a exact deep copy of \"data\" \n// - if callbacks are not defined\n// - if callbacks are resolved with \"value\" without modification\n```\n\n\n\n\n\n## keyCallback\nfunction \"**keyCallback**\" of the `walk` could be used also as a deep '**forEach**' method no matter of the type of the object(object or array). KeyCallback will be executed on keys that have value type: *string, number, bigint, boolean, symbol, null, undefined, and function*.\nObject and arrays will be executed only in objectCallback.\n\n```js\nfunction keyCallbackFn ({value,key,breadcrumbs, IGNORE }) {\n    // value: value for the property;\n    // key:  key of the property;\n    // breadcrumbs: location of the property;\n    // IGNORE: constant. Return it if key-value pair should be ignored;\n    // Callback should return the value of the property. To ignore property, return constant argument IGNORE\n  }\n\nlet result = walk ({ data, keyCallback: keyCallbackFn });  // It's the short way to provide only key-callback. Callback functions are optional.\n// let result = walk ({ data, keyCallback, objectCallback });  // If both callbacks are available\n```\n\n\n## objectCallback\n\nOptional callback function that is started on each object property including 'root'. Function should return object or will be ignored in copy process.\n\n```js\nfunction objectCallbackFn ({ value, key, breadcrumbs, IGNORE }) {\n      // value: each object during the walk\n      // key: key of the object\n      // breadcrumbs: location of the object\n      // IGNORE: Constant. Return it if key-value pair should be ignored;\n      // object callback should return something.\n}\n\nlet result = walk ({ data, keyCallback:keyCallbackFn, objectCallback : objectCallbackFn })\n```\n\n**IMPORTANT: Object-callbacks are executed always before key-callbacks. If we have both callbacks, then key-callbacks will be executed on the result of object-callback.**\n\nSkip key-callbacks by not defining them:\n```js\n let result = walk ({ data, objectCallback: objectCallbackFn })   // ignore keyCallback\n```\n\n\n## Installation\n\nInstall for node.js projects by writing in your terminal:\n\n```\nnpm install @peter.naydenov/walk\n```\n\nOnce it has been installed, it can be used by writing this line of JavaScript:\n```js\nimport walk from '@peter.naydenov/walk'\n```\n\n\n\n## How to use it\n\n### Deep copy\n```js\nlet myCopy = walk ({ data:x })   // where x is some javascript data structure\n```\n\n\n\n### Deep 'forEach'\n```js\nlet x = {\n          ls    : [ 1,2,3 ]\n        , name  : 'Peter'\n        , props : {\n                      eyeColor: 'blue'\n                    , age     : 47\n                    , height  : 176\n                    , sizes : [12,33,12,21]\n                }\n    };\n\nwalk ({ data:x, keyCallback : ({value,key, breadcrumbs}) =\u003e {\n                  console.log (`${key} ----\u003e ${value}`)   // Show each each primitive couples key-\u003evalue\n                  console.log ( `Property location \u003e\u003e ${breadcrumbs}`)\n                  // example for breadcrumbs: 'age' will looks like this : 'root/props/age'\n              }\n    })\n```\n\n\n### Ignore a key\n\n```js\nlet x = {\n          ls    : [ 1,2,3 ]\n        , name  : 'Peter'\n        , props : {\n                      eyeColor: 'blue'\n                    , age     : 47\n                    , height  : 176\n                    , sizes : [12,33,12,21]\n                }\n    };\nlet result = walk ({ data:x, keyCallback : ({ value, key, IGNORE }) =\u003e {\n                        if ( key === 'name' )   return IGNORE\n                        return value\n                })\n// result will copy all properties from x without the property 'name'.\n// result.name === undefined\n```\n\n\n### Mask values\n\n```js\nlet x = {\n          ls    : [ 1,2,3 ]\n        , name  : 'Peter'\n        , props : {\n                      eyeColor: 'blue'\n                    , age     : 47\n                    , height  : 176\n                    , sizes : [12,33,12,21]\n                }\n    };\nlet result = walk ({ data:x, keyCallback : () =\u003e 'xxx' })\n// 'result' will have the same structure as 'x' but all values are 'xxx'\n// {\n//      ls    : [ 'xxx','xxx','xxx' ]\n//    , name  : 'xxx'\n//    , props : {\n//                  eyeColor: 'xxx'\n//                , age     : 'xxx'\n//                , height  : 'xxx'\n//                , sizes : ['xxx','xxx','xxx','xxx']\n//             }\n//   } \n```\n\n### Change object on condition\n\n```js\nlet x = {\n          ls    : [ 1,2,3 ]\n        , name  : 'Peter'\n        , props : {\n                      eyeColor: 'blue'\n                    , age     : 48\n                    , height  : 176\n                    , sizes : [12,33,12,21]\n                }\n    };\n\nfunction objectCallback ({ value:obj, key, breadcrumbs }) {\n    if ( key === 'root' ) return obj   // Add this row to ignore 'root' object\n    const {age, height} = obj;\n    if ( age \u0026\u0026 age \u003e 30 ) {\n            return { age, height }\n        }\n    return obj\n}\n\nlet result = walk ({ data:x, objectCallback })\n// 'result.props' will have only 'age' and 'height' properties.\n// {\n//      ls    : [ 1,2,3 ]\n//    , name  : 'Peter'\n//    , props : {\n//                  age     : 48\n//                , height  : 176\n//             }\n//   } \n```\n\n## Limitations\n- `walk` keyCallback can return only primitives;\n- `walk` can not execute another `walk` from inside of the callbacks;\n- It's not recomended to use any async operations in the callbacks. Could compromise the result without any warning;\n\nThese limitations are covered in a bit larger library - [walk-async](https://github.com/PeterNaydenov/walk-async). Interface is very simular but result is coming as a promise and callbacks should be resolved or rejected.\n\n## Links\n- [Release history](Changelog.md)\n- [ Walk-async library](https://github.com/PeterNaydenov/walk-async)\n- [ Documentation version 4.x.x](https://github.com/PeterNaydenov/walk/blob/master/README_v.4.x.x.md)\n- [ Migration guide ](https://github.com/PeterNaydenov/walk/blob/master/Migration.guide.md)\n\n\n\n## Credits\n'@peter.naydenov/walk' was created and supported by Peter Naydenov.\n\n## License\n'@peter.naydenov/walk' is released under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeternaydenov%2Fwalk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeternaydenov%2Fwalk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeternaydenov%2Fwalk/lists"}