# Sparse array iterators

**URL:** <https://es.discourse.group/t/sparse-array-iterators/952>\
**Category:** 💡 Ideas\
**Created:** [August 29, 2021, 9:03am UTC](https://es.discourse.group/t/sparse-array-iterators/952 "2021-08-29T09:03:07Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [August 29, 2021, 9:03am UTC](https://es.discourse.group/t/sparse-array-iterators/952/1 "2021-08-29T09:03:07Z")

</div>

I'd like to have array iterator that skips gaps (like `forEach`), and visits elements added during iteration (unlike `forEach`).

Pseudo-implementation:

```javascript
Array.prototype.sparseEntries = function* sparseEntries() {
  for (const [i, v] of this.entries()) {
    if (i in this) {
      yield [i, v];
    }
  }
}

```

Example:

```javascript
function f(v, i, a) {
  console.log(`${i}: ${v}`); 
  if (v < 10) a[2 * i] = 3 * v;
}

```

```javascript
> [,,3].forEach(f);
2: 3

```

```javascript
> { let a = [,,3]; for (let [i, v] of a.sparseEntries()) f(v, i, a); }
2: 3
4: 9
8: 27

```

---

<div class="post-metadata">

**Author:** ![claudepache](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudepache/32/236_2.png) [@claudepache](https://es.discourse.group/u/claudepache)\
**Post date:** [August 29, 2021, 10:54am UTC](https://es.discourse.group/t/sparse-array-iterators/952/2 "2021-08-29T10:54:30Z")

</div>

> [@lightmare](#):
>
> `if (this.slice(i, i+1).some(() => true)) {`

Is that the new way to write

```js
if (i in this) {

```

?

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [August 29, 2021, 10:56am UTC](https://es.discourse.group/t/sparse-array-iterators/952/3 "2021-08-29T10:56:03Z")

</div>

Do you think adding this to the set of built in methods would encourage people to use sparse arrays more often?

Does keeping these helpers as independent libraries, e.g on npm, cause a significant issue?

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [August 29, 2021, 11:16am UTC](https://es.discourse.group/t/sparse-array-iterators/952/4 "2021-08-29T11:16:28Z")

</div>

> [@claudepache](#):
>
> Is that the new way to write
> 
> `if (i in this) {`

Thank you, that does exactly what I wanted.

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [August 29, 2021, 12:21pm UTC](https://es.discourse.group/t/sparse-array-iterators/952/5 "2021-08-29T12:21:50Z")

</div>

> [@aclaymore](#):
>
> Do you think adding this to the set of built in methods would encourage people to use sparse arrays more often?

Not as a primary goal. Rather, starting from a point where you already have (or consider to use) a sparse array, facilitating usage in for loops.

> [@aclaymore](#):
>
> Does keeping these helpers as independent libraries, e.g on npm, cause a significant issue?

Significant, no. A library function filtering indices would add a little more overhead to an already slow operation. I'd probably keep checking `if (idx in ary)` by hand.

```sh
// forEach
pnpx benchmark -e 'a = []; a[1e6] = 1; a.forEach((v, i) => out = v);'
✔ eval-1 x 31.30 ops/sec ±0.16% (54 runs sampled)

// for...of
$ pnpx benchmark -e 'a = []; a[1e6] = 1; for (let [i, v] of a.entries()) out = v;'
✔ eval-1 x 21.93 ops/sec ±0.52% (39 runs sampled)

// for...of + if...in
$ pnpx benchmark -e 'a = []; a[1e6] = 1; for (let [i, v] of a.entries()) if (i in a) out = v;'
✔ eval-1 x 12.89 ops/sec ±1.02% (35 runs sampled)

```

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [August 31, 2021, 6:33am UTC](https://es.discourse.group/t/sparse-array-iterators/952/6 "2021-08-31T06:33:38Z")

</div>

Note: you do want to be careful to make sure `i` is a number - that will also return `true` for `length` as well as any other prototype method. (I would personally still recommend using `hasOwnProperty` to ensure that `length` is the only exception, for security reasons if nothing else.)
