1

I checked the MDN for both flatMap/map but still cannot understand why the third test fails:

  describe("mysterious flatMap", () => {
    it("an array will be mapped to an array of `undefined` when its element NOT set", () => {
      const mapped = new Array(1).map(() => "x");
      expect(mapped.length).toBe(1); //OK
      expect(mapped[0]).toBe(undefined); // OK
    });
    it("flatMap can join array of `undefined`", () => {
      const flat = [undefined].flatMap((_) => [undefined]);
      expect(flat.length).toBe(1); // OK
      expect(flat[0]).toBe(undefined); //OK
    });
    it("but flatMap can NOT join the array which is created without elements set, why ??", () => {
      const flat = [undefined].flatMap((_) => new Array(1).map(() => "x"));
      expect(flat.length).toBe(1); // Error, Received: 0
      expect(flat[0]).toBe("x");
    });
  });

I also created an online test on codesandbox

Smartkid
  • 1,772
  • 2
  • 25
  • 34
  • 2
    Makes perfect sense. Flatmapping an array with one element into an empty array leads to...an empty array. Not sure why you expected otherwise. – VLAZ Feb 18 '21 at 14:26
  • `flat` and `flatMap` remove holes. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat#flattening_and_array_holes – adiga Feb 18 '21 at 14:27
  • 1
    "*"an array will be mapped to an array of `undefined` when its element NOT set"*" that's not really what happens. You have an array of empty slots. It's not an array of `undefined`. – VLAZ Feb 18 '21 at 14:27
  • Incidentally, that's also what a sparse array is - full of holes! – VLAZ Feb 18 '21 at 14:53

1 Answers1

2

From MDN

flatMap is identical to a map() followed by a flat() of depth 1, but slightly more efficient than calling those two methods separately

And

The flat method removes empty slots (holes) in arrays


This code

new Array(1).map(() => "x")

does NOT return [undefined]. It creates a sparse array (an array of holes)

(JavaScript "new Array(n)" and "Array.prototype.map" weirdness)

So, your last block of code is equivalent to [empty x 1].flat(1) which results in an empty array.

adiga
  • 34,372
  • 9
  • 61
  • 83
  • 1
    Even more precisely, `new Array(1).map(() => "x")` is equivalent to just having `new Array(1)` because `.map` will skip all empty slots. Which is all of them. – VLAZ Feb 18 '21 at 14:45