{"record":{"id":"721b4b6896ee3896","repo":"oxc-project/oxc","slug":"prefer-find-over-filtering-and-accessing-the-fir","errorCode":null,"errorMessage":"Prefer `find` over filtering and accessing the first result.","messagePattern":"Prefer `find` over filtering and accessing the first result\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/unicorn/prefer_array_find.rs","lineNumber":18,"sourceCode":"use oxc_ast::{\n    AstKind,\n    ast::{\n        Argument, AssignmentTarget, BindingPattern, CallExpression, Expression,\n        SimpleAssignmentTarget, UnaryOperator,\n    },\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::{GetSpan, Span};\n\nuse crate::{\n    AstNode, ast_util::is_method_call, context::LintContext, rule::Rule,\n    utils::call_expr_member_expr_property_span,\n};\n\nfn prefer_array_find_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Prefer `find` over filtering and accessing the first result.\")\n        .with_help(\"Use `find(predicate)` instead of `filter(predicate)[0]` or similar patterns.\")\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct PreferArrayFind;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Encourages using `Array.prototype.find` and `Array.prototype.findLast` instead of\n    /// taking the first or last matching element from `filter(...)`.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Using `filter(...)[0]` or array destructuring to get the first match is less\n    /// efficient and more verbose than using `find(...)`. `find` and `findLast`\n    /// short-circuit when a match is found, whereas `filter` evaluates the entire array.","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/unicorn/prefer_array_find.rs#L1-L36","documentation":"Lint diagnostic from oxlint's `unicorn/prefer-array-find` rule. Calling `.filter(predicate)` and then taking element `[0]` (or `.shift()`/`.pop()` for last) scans the whole array and allocates an intermediate array; `Array.prototype.find` / `findLast` stops at the first match. The rule flags the filter-then-index pattern and recommends `find`.","triggerScenarios":"Member-call chains like `users.filter(isAdmin)[0]`, `items.filter(x => x.active).shift()`, `logs.filter(severe).pop()` — i.e. `is_method_call` on `filter` followed by immediate element access. Reported during oxlint scans when the rule is on.","commonSituations":"Very common in older codebases written before ES2015 `find`, or by developers coming from languages without `find`. Also hits performance-sensitive paths where the array is large — the lint warning often coincides with a real O(n) waste. Appears in bulk when enabling the unicorn category.","solutions":["Replace `arr.filter(fn)[0]` with `arr.find(fn)` and `arr.filter(fn).pop()` with `arr.findLast(fn)`.","Run `oxlint --fix` — the rule rewrites the chain automatically when the predicate is reusable.","Keep `filter` when you truly need ALL matches afterwards (not just the first); suppress the line if it is a deliberate pattern.","Disable via `\"unicorn/prefer-array-find\": \"off\"` if the team prefers explicit filter chains."],"exampleFix":"// before\nconst admin = users.filter(u => u.role === 'admin')[0];\n\n// after\nconst admin = users.find(u => u.role === 'admin');","handlingStrategy":"validation","validationCode":"// oxlint --fix --filter unicorn/prefer-array-find src/\n// CI gate: oxlint --deny-warnings src/","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer `find`/`findLast` when you need one match; reach for `filter` only when you consume all matches.","Run `oxlint --fix` on a scheduled basis to clear accumulated filter-index chains."],"tags":["oxlint","unicorn","arrays","performance","refactor","autofix"],"backgroundTag":"lint-rule-violation","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}