【问题标题】:Array.map doesn't seem to work on uninitialized arrays [duplicate]Array.map 似乎不适用于未初始化的数组[重复]
【发布时间】:2013-12-18 11:27:23
【问题描述】:

我正在尝试使用 map 函数在未初始化的数组上设置默认值,但它似乎不起作用,关于如何设置默认值的任何想法?

考虑一下我在 Chrome 控制台中尝试过的这段代码 sn-p。

> var N = 10;
> var x = new Array(N);
> x
  [undefined x 10]

> x.map(function(i) { return 0;});
  [undefined x 10]

我希望数组初始化为 0。

【问题讨论】:

    标签: javascript arrays


    【解决方案1】:

    .map() 函数会跳过从未被赋值的条目。因此,在像您这样新构建的数组上,它基本上什么都不做。

    Here is the MDN description.

    【讨论】:

      【解决方案2】:

      使用.map(),未定义的元素将被跳过并且不会传递给回调,因此如果您有一个没有元素的数组实际上包含任何内容,则永远不会调用回调。

      来自ECMA script 262, 5.1 specification,第 15.4.4.19 节:

      callbackfn 仅对数组的元素调用 存在;数组的缺失元素不会调用它。

      【讨论】:

        【解决方案3】:

        如果您想填充数组,可以使用Array(5).fill(),然后这些方法将按预期工作——请参阅 aasha7 的备用相关答案。较旧的预填充方法包括:

        Array.apply(null, new Array(5)).map(function() { return 0; });
        // [ 0, 0, 0, 0, 0 ]
        

        看了posts linked in the comments中的一个,我发现这也可以写成

        Array.apply(null, {length: 5}).map(function() { return 0; });
        

        但是,尝试对未定义的值使用 .map 将不起作用。

        x = new Array(10);
        x.map(function() { console.log("hello"); });
        
        // so sad, no "hello"
        // [ , , , , , , , , ,  ]
        

        .map 将跳过未定义的值:(

        【讨论】:

        • +1;这里的问题是map 跳过了从未被赋值过的indexes。将Object.keys(new Array(2))(无可枚举属性)与Object.keys([undefined, undefined])(两个可枚举属性,01)进行比较。在第一种情况下,数组没有分配给任何索引的值;在第二种情况下,索引01 已被赋值为undefined
        • @apsillers,你是对的。澄清一下,var x = new Array(5); 只有x.length == 5Array.prototype。除此之外,没有设置可枚举的键。
        • 非常酷的技巧 - 我仍在尝试了解“new Array(5)”与“Array.apply(null, new Array(5))”之间的区别
        • @Raja 你应该去看看Ziraks explanation on this
        • 我遇到了这个问题,它实际上确实undefined 值起作用(在 javascript 类型中未定义),只是不适用于未初始化的值。
        【解决方案4】:

        您可以用零填充数组using this function

        function fillArrayWithNumber(n) {
          var arr = Array.apply(null, Array(n));
          return arr.map(function (x, i) { return 0; });
        }
        
        fillArrayWithNumber(5); // [0,0,0,0,0]
        

        或者稍作改动,您可以改用索引:

        function fillArrayWithIndex(n) {
          var arr = Array.apply(null, Array(n));
          return arr.map(function (x, i) { return i; });
        }
        
        fillArrayWithIndex(5); // [0,1,2,3,4]
        

        Fiddle

        【讨论】:

          【解决方案5】:

          ECMAScript 语言规范是这样描述的

          这是Array.prototype.map 的相关部分,如 (§15.4.4.19) 所述

          • ...
          • 8。重复,而k < len
            • a)Pk 成为ToString(k)
            • b)kPresent 成为使用参数Pk 调用O 的[[HasProperty]] 内部方法的结果。
            • c) 如果kPresenttrue,那么
              • 施展魔法
          • ...

          由于您的数组中没有已初始化的成员,因此调用例如new Array (1337).hasOwnProperty (42)evaluates 为false,因此不满足步骤 8.c 中的条件。

          不过,你可以使用一点“hack”来做你想做的事。

          Array.apply(null, { length: 5 }).map(Number.call, Number) //[0, 1, 2, 3, 4]

          它的工作原理已经彻底了解explained by @Zirak

          【讨论】:

            【解决方案6】:

            我只想指出,您现在可以这样做:

            Array(2).fill().map(_ => 4);
            

            这将返回[4, 4]

            【讨论】:

            • newnull 不是必需的,这与 Array(10).fill().map(_ => 0) 相同。无论如何都要 +1
            • 或更短的Array(10).fill(0)
            • [...Array(2)].map(_=>4);
            【解决方案7】:

            在以前的答案的基础上,有新的更短的语法。 OP 想要创建一个由 N 项初始化为 0 的数组。

            var N = 10;
            var x = new Array(N).fill(0);
            // x is now: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
            

            您也不需要new - 在这种情况下它是可选的。

            检查compatibility of your target platform 和/或使用 pollyfill(如果不可用)。

            【讨论】:

              【解决方案8】:

              没有Array.prototype.fill也可能的解决方案:

              [...Array(10)].map((_, idx) => idx); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-02-15
                • 2016-04-13
                • 1970-01-01
                • 2011-08-18
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多