prefer-sets

Converts array membership checks into Set and Map lookups in TypeScript code.

2|1|Updated Jun 28, 2026
One-click install
npx skills add https://github.com/lxsmnsyc/overwander --skill prefer-sets-lxsmnsyc
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: prefer-sets
Source: https://github.com/lxsmnsyc/overwander/tree/main/.agents/skills/prefer-sets
Command: npx skills add https://github.com/lxsmnsyc/overwander --skill prefer-sets-lxsmnsyc

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Codebases often test membership with .includes(), .indexOf(), or .some() on arrays, which performs an O(n) scan on every query and obscures intent. This Skill enforces a consistent rule: any "is X one of these values" check uses a Set (or Map when a value is attached) for O(1) hash lookups. ## Core Features & Use Cases - Static lookup tables: Declares constant collections as const FOO = new Set<T>([...]) at module scope and queries them with .has() instead of ARRAY.includes(x). - Dynamic membership tracking: Uses Set.add/delete for mutable collections like units on a field or seen ids, replacing array.push plus indexOf/splice removal patterns. - Disguised membership detection: Flags predicate scans that reduce to identity comparison (arr.some(v => v === x)) and converts them to Set lookups. - Use Case: While reviewing a battle engine, you find MAJOR_STATUS_CONDITIONS.some((s) => s === status); the Skill rewrites it as a module-level MAJOR_STATUS Set queried with .has(status). ## Quick Start Review this TypeScript file and convert every array membership check into a Set or Map lookup, keeping arrays only where order or genuine predicate filtering matters.

Frequently Asked Questions about prefer-sets

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I replace Array.includes with a Set in TypeScript?▼

Declare the collection as `const FOO = new Set<T>([...])` at module scope and query it with `FOO.has(x)` instead of `FOO.includes(x)`. This changes membership checks from an O(n) scan to an O(1) hash lookup.

When should I use a Set instead of an array for membership checks?▼

Use a Set whenever code answers "is this value in this collection", especially for collections queried more than once or larger than a couple of entries. Predicate scans like `arr.some(v => v === x)` are membership checks in disguise and should also become Sets.

When is an array still the right choice over a Set?▼

Keep an array when order matters, such as priority lists or iteration sequences, when the collection is only ever iterated, or when the callback does real filtering work like `arr.some(v => v.alive && v.team === t)`. Tuples and JSON-shaped data also stay as arrays.

How do I track dynamic membership like active units or seen ids?▼

Keep a Set, or a Map when a value is attached, and mutate it with `add` and `delete`. Never use `array.push` combined with `indexOf` and `splice` for removal, which is slower and error-prone.

What if an exported array is used by other modules for iteration?▼

Keep the existing array export so other modules can still iterate it, but add a Set counterpart for membership checks. Callers that only test membership should query the Set rather than scanning the array.