Skip to content
Back to skills

Prefer Sets

ASecurity

Prefer Set (and Map) lookups over Array + .some/.indexOf/.includes for membership checks. Applies whenever writing or reviewing code that tests "is X one of these values". O(1) hash lookup instead of O(n) scan, and intent reads clearer.

  • 5 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 20, 2026
developmentgo

Security analysis

A100/100

Scanned September 20, 2026

npx -y skills add lxsmnsyc/overwander --skill prefer-sets --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Prefer Sets?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Prefer Sets
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lxsmnsyc-prefer-sets/badge)](https://www.skillsdirectory.com/skills/lxsmnsyc-prefer-sets)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: prefer-sets
description: >
  Prefer Set (and Map) lookups over Array + .some/.indexOf/.includes for
  membership checks. Applies whenever writing or reviewing code that
  tests "is X one of these values". O(1) hash lookup instead of O(n)
  scan, and intent reads clearer.
---

When code answers "is this value in this collection?", use a `Set`, not an array scanned with `.some()`, `.indexOf()`, or `.includes()`.

## Rules

- Static lookup tables: declare as `const FOO = new Set<T>([...])` at module scope; query with `FOO.has(x)`. Never `ARRAY.includes(x)` or `ARRAY.some(v => v === x)`.
- Dynamic membership tracking (units on field, seen ids, active instances): keep a `Set` (or `Map` when a value is attached) and mutate with `add`/`delete`. Never `array.push` + `indexOf`/`splice` for remove.
- Predicate scans that reduce to identity comparison (`arr.some(v => v === x)`) are membership checks in disguise — convert the collection to a `Set`.
- `.indexOf(x) !== -1` / `.includes(x)` on any collection queried more than once or larger than a couple of entries: convert.

## When an array is still right

- Order matters (priority lists, learnset levels, iteration sequences).
- The collection is only ever iterated, never membership-tested.
- A genuine predicate scan where the callback does real work (`arr.some(v => v.alive && v.team === t)`) — that is filtering, not membership.
- Tuples/pairs and JSON-shaped data.

## Examples

```ts
// Bad
const PRIMAL = [Weathers.ExtremeSunny, Weathers.HeavyRain];
if (PRIMAL.includes(current)) { ... }
if (MAJOR_STATUS_CONDITIONS.some((s) => s === status)) { ... }

// Good
const PRIMAL = new Set<Weathers>([Weathers.ExtremeSunny, Weathers.HeavyRain]);
if (PRIMAL.has(current)) { ... }
if (MAJOR_STATUS.has(status)) { ... }
```

Existing exported arrays used by other modules for iteration may keep the array export but should add a Set counterpart for membership checks rather than scanning the array.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…