【问题标题】:rewriting Map with forEach用 forEach 重写 Map
【发布时间】:2016-04-15 06:09:40
【问题描述】:

forEach 方法不会返回带有值结果的新字符串。 如果我想用forEach重写map方法,我不能使用命令 push.forEach(array,callback).

我正在尝试使用 forEach 方法将数组中的每个元素乘以 2 并将其存储在一个新数组中。我不想要关于使用 map 方法的建议,因为我知道它已经这样做了。

不使用forEach 方法,我的代码如下:

function MultiplyByTwo(num) {
    return num * 2;
}

function HostMultiplyByTwo(array,instructions) {
    var output = [];
    for (i=0;i<array.length;i++) {
        output.push(instructions(array[i]))
    }
    return output;
}

var endresult = HostMultiplyByTwo([1,2,3],MultiplyByTwo)

如果forEach 函数如下所示:

function forEach(array, callback) {
    for (var i =0;i<array.length;i++) {
        var result = callback(array[i])
    }
    return result;
}

现在我希望能够使用forEach 方法运行HostMutiplyByTwo。这是我尝试过的。

function HostMultiplyByTwo(array,instructions) {
    var output = [];
    forEach(array,instructions) {
        output.push(result)
    }
    return output;
}

var endresult = HostMultiplyByTwo([1,2,3],MultiplyByTwo)

由于某种原因,这显然不起作用。我知道forEach 方法只是遍历第一个参数并在第一个参数的第二个参数中执行函数。

  • 之后它会在某处存储该操作的结果吗?
  • 有没有一个地方可以让我看到我的浏览器使用的实际内置函数“forEach”,因为我无法找到它的确切定义?
  • 我不能使用 push.forEach(array,instruction)。
  • 假设我有一个名为“freeze”的数组。是否需要“冻结”,对“冻结”中的每个元素执行操作,然后将这些操作的结果保存回“冻结”?
  • 我这样做是因为我想练习使用闭包和回调函数。我知道 map 在对每个元素执行函数后会返回一个数组,但我不明白如何使用 forEach 执行此操作。
  • 我在网上看到您可以使用“this.forEach”,但我无法理解计算机如何解释“this”。

非常感谢任何帮助。

【问题讨论】:

  • FWIW,你已经自己重新实现了map。您的HostMultiplyByTwo() 实际上是map 的简单版本。虽然它没有实现 ECMAscript 标准规定的map 的所有功能,但它类似于其他语言中的map 函数。

标签: javascript loops dictionary asynchronous foreach


【解决方案1】:

你认为这应该做什么?

forEach(array,instructions) {
    output.push(result)
}

forEach 只是一种方法 - 它不是像 if 这样的构造。如果您使用函数语法(而不是内置方法),则需要执行类似

forEach(array, function (element) {
    output.push(instructions(element))
});

请注意,匿名函数将函数的结果推送到输出 - 您可以从 map 免费获得。

您可以通过使用命名闭包来避免匿名函数

var pusher = function (element) {
    output.push(instructions(element))
};

forEach(array, pusher);

您甚至可以动态构建闭包

var pusherCreator = function (outputArray, callback) {
    var pusher = function(element) {
        outputArray.push(callback(element));
    };

    return pusher;
};

forEach(array, pusherCreator(output, instructions));

【讨论】:

  • 有没有办法让“指令”成为一个函数而不必使用“函数(元素)”//因为那是一个匿名函数正确吗?
  • @JonathanMitchell 这需要一个闭包。我将添加一个示例。
【解决方案2】:

forEach 函数中你有:

for (var i =0;i<array.length;i++) {
  var result = callback(array[i])
}

它只是在每次迭代时为 result 分配一个新值。您需要将值分配给数组,因此:

var result = [];
for (var i =0;i<array.length;i++) {
  result.push(callback(array[i]));
}

现在在 HostMultiplyByTwo 函数中,您只需要:

var output = forEach(array,instructions)
return output;

或者只是:

return forEach(array,instructions);

请注意,按照惯例,以大写字母开头的变量名是为构造函数保留的。全部大写的变量用于常量。

所以整个事情看起来像:

function multiplyByTwo(num) {
    return num * 2;
}

function forEach(array, callback) {
  var result = [];
  for (var i=0; i<array.length; i++) {
    result.push(callback(array[i]));
  }
  return result;
}

function hostMultiplyByTwo(array,instructions) {
    return forEach(array,instructions)
}

document.write(hostMultiplyByTwo([1,2,3], multiplyByTwo));

请注意,如果要处理稀疏数组并正确复制 mapforEach(仅访问存在的成员),则需要测试每个 i 源数组的成员存在,所以 forEach 变为:

  for (var i=0; i<array.length; i++) {
    if (array.hasOwnProperty(i)) {
      result[i] = callback(array[i]);
    }
  }

所以不存在的成员仍然不存在。

【讨论】:

  • 不,他不需要在forEach 中创建一个数组并推入它。您是对的,他不需要分配计算结果或返回它,但这是无害的。本质上,您是在建议将forEach 转换为map,这不是重点。
  • @torazaburo—"我正在尝试使用 forEach 方法将数组中的每个元素乘以 2 并将其存储在新数组中" 所以是的,OP 必须创建一个新数组。如果在 forEach 函数中没有发生这种情况,那么它必须在 HostMultiplyByTwo 函数中发生,并且 forEach 必须返回一些内容,并且该内容必须是另一个数组,因为函数只能返回一个值。
  • @torazaburo——哦,主题是“rewriting Map with forEach”,表示需要一种map替换。跨度>
  • 这正是他所谓的HostMultiplyByTwo 的例程。
  • @torazaburo——在这种情况下,HostMultiplyByTwo 必须将结果数组传递给 forEach 进行修改,类似于 forEach(source, fn, target) 和如果 target 未定义,直接对source 进行操作,否则将结果放入target。这是我看到的唯一替代方法,因为必须在某个时间创建一个新数组,并且 forEach 必须分配值。
猜你喜欢
  • 1970-01-01
  • 2020-01-20
  • 2017-10-17
  • 2021-09-30
  • 2012-01-26
  • 1970-01-01
  • 1970-01-01
  • 2022-12-19
  • 2020-03-27
相关资源
最近更新 更多