{"id":19443784,"url":"https://github.com/aretecode/eslint-plugin-no-for-each","last_synced_at":"2025-07-02T21:34:11.589Z","repository":{"id":85930842,"uuid":"73027263","full_name":"aretecode/eslint-plugin-no-for-each","owner":"aretecode","description":"eslint plugin for changing forEach into for loop","archived":false,"fork":false,"pushed_at":"2017-03-18T08:28:16.000Z","size":41,"stargazers_count":3,"open_issues_count":6,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-25T08:16:29.265Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aretecode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2016-11-07T00:02:24.000Z","updated_at":"2021-08-31T03:01:46.000Z","dependencies_parsed_at":"2023-05-03T15:33:52.726Z","dependency_job_id":null,"html_url":"https://github.com/aretecode/eslint-plugin-no-for-each","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aretecode/eslint-plugin-no-for-each","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aretecode%2Feslint-plugin-no-for-each","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aretecode%2Feslint-plugin-no-for-each/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aretecode%2Feslint-plugin-no-for-each/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aretecode%2Feslint-plugin-no-for-each/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aretecode","download_url":"https://codeload.github.com/aretecode/eslint-plugin-no-for-each/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aretecode%2Feslint-plugin-no-for-each/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263218935,"owners_count":23432581,"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":[],"created_at":"2024-11-10T15:44:09.128Z","updated_at":"2025-07-02T21:34:11.515Z","avatar_url":"https://github.com/aretecode.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# eslint-plugin-no-for-each\n[![Build Status](https://travis-ci.org/aretecode/eslint-plugin-no-for-each.svg?branch=master)](https://travis-ci.org/aretecode/eslint-plugin-no-for-each)\n[![MIT License][license-image]][license-url]\n[![NPM version][npm-image]][npm-url]\n[![Dependencies][david-deps-img]][david-deps-url]\n[![Standard JS Style][standard-image]][standard-url]\n\n[npm-image]: https://img.shields.io/npm/v/eslint-plugin-no-for-each.svg\n[npm-url]: https://npmjs.org/package/eslint-plugin-no-for-each\n[david-deps-img]: https://david-dm.org/aretecode/eslint-plugin-no-for-each.svg\n[david-deps-url]: https://david-dm.org/aretecode/eslint-plugin-no-for-each\n[standard-image]: https://img.shields.io/badge/code%20style-standard%2Bes6+-brightgreen.svg\n[standard-url]: https://github.com/crocodilejs/eslint-config-aretecode\n[license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat\n[license-url]: https://spdx.org/licenses/MIT\n\n\nWhat it does? Fix `forEach`, `for in`, and `for of` loops.\n\nBefore:\n\n![image](https://cloud.githubusercontent.com/assets/4022631/20047084/8ed348e0-a465-11e6-90f4-4715f5498699.png)\n\nAfter:\n\n`['error', 'cache-length']`\n![image](https://cloud.githubusercontent.com/assets/4022631/20047228/fa5ed9fc-a466-11e6-87b6-f490be782748.png)\n\n`['error']`\n![image](https://cloud.githubusercontent.com/assets/4022631/20047232/ffab29a6-a466-11e6-8dcf-436c40d97757.png)\n\nhttps://jsperf.com/foreach-vs-for-loop-vs-for-in-vs-for-of-vs-babel-for-of\n\ncan copy paste in, hit save, autofix loops without doing the whole project if you use immutables or need the loops\n```\n/* eslint 'no-for-each/no-for-each': 2 */\n/* eslint 'no-for-each/no-for-in': 2 */\n/* eslint 'no-for-each/no-for-of': 2 */\n```\n\n## [Installation](#installation)\n\nYou'll first need to install [ESLint](http://eslint.org):\n\n```\n$ npm i eslint --save-dev\n```\n\nNext, install `eslint-plugin-no-for-each`:\n\n```\n$ npm install eslint-plugin-no-for-each --save-dev\n```\n\n**Note:** If you installed ESLint globally (using the `-g` flag) then you must also install `eslint-plugin-no-for-each` globally.\n\n## [Configuration](#configuration)\nAdd `no-for-each` to the plugins section of your `.eslintrc` configuration file.\nThen configure the rules you want to use under the rules section.\n\n- default: `1` or `[\"error\"]`\n- cache-length: `2`\n\n```json\n{\n  \"plugins\": [\n    \"no-for-each\"\n  ],\n  \"rules\": {\n    \"no-for-each/no-for-each\": 2,\n    \"no-for-each/no-for-of\": 2,\n    \"no-for-each/no-for-in\": 2,\n  }\n}\n```\n\n## two additional WIP rules\n```json\n\"rules\": {\n  \"...\": \"...\",\n  \"no-for-each/cache-for-length\": 2,\n  \"no-excessive-blank-lines\": 2\n}\n```\n\n# Resources\n- https://www.kenneth-truyers.net/2016/05/27/writing-custom-eslint-rules/\n- https://github.com/airbnb/javascript/issues/851\n- https://insideops.wordpress.com/2015/12/08/creating-custom-rules-for-eslint/\n- https://medium.com/tumblbug-engineering/creating-an-eslint-plugin-87f1cb42767f#.z5t30ge87\n- http://stackoverflow.com/questions/34130718/how-to-create-customized-eslint-rules/34186003\n- http://stackoverflow.com/questions/38278273/eslint-code-vs-whitespace-values-for-fixable\n- https://github.com/eslint/eslint/commit/a9a4652b2ce92858d90243e7bb8693f458a14783\n- https://github.com/facebookincubator/create-react-app/issues/272\n- https://github.com/facebookincubator/create-react-app/issues/274\n- https://github.com/yannickcr/eslint-plugin-react/blob/master/lib/rules/jsx-equals-spacing.js#L18\n- https://github.com/jfmengels/eslint-rule-documentation/blob/master/contributing.md\n- https://github.com/Gillespie59/eslint-plugin-angular\n- http://eslint.org/docs/developer-guide/working-with-rules\n- http://eslint.org/blog/2016/07/eslint-new-rule-format\n- http://eslint.org/docs/developer-guide/working-with-rules-new\n- https://github.com/buildo/eslint-plugin-no-loops (had no fixing, was no loops in general)\n- https://github.com/airbnb/javascript#iterators--nope\n- https://www.paypal-engineering.com/2014/12/12/maintaining-javascript-code-quality-with-eslint/\n- https://babeljs.io/repl/\n- http://eslint.org/docs/rules/\n\n# known bugs\n- [ ] properly parse `Object.keys(apples).forEach(apple =\u003e delete apples[apple])` because it replaces `apple` with new var, but not `apples` so it leaves the `s`\n- [ ] nested loops, will do this soon\n- [x] truncating body at some point\n\n# jsperf\n```javascript\nvar testData = [];\nfor (var i = 0; i \u003c 100; i++) {\n  testData.push(i);\n}\n\n// forEach\nvar res = 0;\ntestData.forEach(function(x) {\n  res += x;\n});\n\n// for\nvar res = 0;\nfor (var i = 0; i \u003c testData.length; i++) {\n  res += testData[i];\n}\n\n// for optimized\nvar res = 0;\nfor (var i = 0, len = testData.length; i \u003c len; i++) {\n  res += testData[i];\n}\n\n// reduce\nvar res = testData.reduce(function(sum, x) {\n  return sum + x;\n}, 0);\n\n\n// while\nvar res = 0;\nvar i = testData.length;\nwhile (i--) {\n    res += testData[i];\n}\n\n// for in\nvar res = 0;\nfor (var data in testData) {\n  res += testData[i];\n}\n\n\n// for of\nvar res = 0;\nfor (var data of testData) {\n  res += testData[i];\n}\n\n\n// for of babel\nvar res = 0;\nvar _iteratorNormalCompletion = true;\nvar _didIteratorError = false;\nvar _iteratorError = undefined;\n\ntry {\n  for (var _iterator = testData[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n    var value = _step.value;\n\n    console.log(value);\n  }\n} catch (err) {\n  _didIteratorError = true;\n  _iteratorError = err;\n} finally {\n  try {\n    res += testData[i];\n    if (!_iteratorNormalCompletion \u0026\u0026 _iterator.return) {\n      _iterator.return();\n    }\n  } finally {\n    if (_didIteratorError) {\n      throw _iteratorError;\n    }\n  }\n}\n```\n\n\n# @NOTES:\n---\ncould keep option `cache-length`\nbut since we are using an object,\nseems silly to call object.keys 2x\n---\nwe do not use body.body because\n- 1) not always there\n- 2) we want to keep curly braces (or lack of from the source\n----\n\n(when it has proper configs and has large files to test, then release 1.0.0)\n# @TODO:\n- [ ] add config option for `cache-length-inside-loop` (var i = 0, len = varName.length; ...)\n- [ ] recommend let =\u003e const rule\n- [ ] add large js files to test failed fixing \u0026 safety\n- [ ] isDev | isTest helper funcs\n- [ ] ^ add args in tests for `devtest`\n- [ ] comment on readmes\n- [ ] move todos to issues\n- [ ] use type in the `left` of the loop such as `const`, `let`, `var`\n- [ ] o.hasOwnProperty for for in/of\n- [ ] (lower priority) make a guide how to make an eslint plugin\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faretecode%2Feslint-plugin-no-for-each","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faretecode%2Feslint-plugin-no-for-each","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faretecode%2Feslint-plugin-no-for-each/lists"}