javascript:带孔数组上的循环函数

标签 javascript arrays ecmascript-6

如果我创建一个稀疏数组(其中有一些洞),数组函数,如.map().reduce(), .forEach() 将跳过这些漏洞。

[, , 1, , 2].forEach((item) => console.log(item)) 
// 1
// 2

我正在寻找的是一个不会跳过漏洞的数组函数,其工作原理如下:

[, , 1, , 2].fullForEach((item) => console.log(item))
// undefined
// undefined
// 1
// undefined
// 2

我想在原始数组上循环,而不是将数组中的孔转换为实际的未定义值,即以下都不是我正在寻找的:

Array.from([, , 1, , 2]).forEach();
[...[, , 1, , 2]].forEach();

我正在为此寻找一个功能性解决方案,这意味着我希望获得一个没有任何 for/while 的解决方案循环。

最佳答案

您不应该为此使用Array.prototype.find - 一旦函数返回真值,find 将停止迭代。它只是继续在提供的 console.log 示例中进行迭代,因为 console.log 是一个副作用函数,并且始终返回 undefined,一个非-真实值(value)。

相反,您应该创建自己的迭代器来正确描述您实际想要的行为。正如其他人评论的那样,使用 forwhile 循环没有任何问题 - 这正是像 reducemap 这样的 native 函数的方式 无论如何都已实现。您正在寻找的是创建一个功能性的接口(interface) - 也就是说,您的函数内部看起来如何并不重要;重要的是它的内部结构。您的函数的用户可以以纯函数的方式使用它。

Array.prototype.fullForEach = function (f, env) {
  for (let i = 0; i < this.length; i++)
    f.call(env, this[i], i, this)
}

Array.prototype.fullReduce = function (f, acc, env) {
  for (let i = 0; i < this.length; i++)
    acc = f.call(env, acc, this[i], i, this)
  return acc
}
    
Array.prototype.fullMap = function (f, env) {
  return this.fullReduce((acc, x, i) => [...acc, f.call(env, x, i, this)], [], env)
}

const arr = [,,,2,,]

arr.fullForEach((x, i, xs) => console.log(x, i, xs))
// undefined 0 [ , , , 2,  ]
// undefined 1 [ , , , 2,  ]
// undefined 2 [ , , , 2,  ]
// 2 3 [ , , , 2,  ]
// undefined 4 [ , , , 2,  ]

console.log(arr.fullMap(x => x ? x : 'void'))
// [ 'void', 'void', 'void', 2, 'void' ]

console.log(arr.fullMap(function (x) { return x ? x : this.default }, { default: 'void' }))
// [ 'void', 'void', 'void', 2, 'void' ]

console.log(arr.fullReduce((acc, x) => x ? acc + x : acc + '-', ''))
// ---2-

console.log(arr.fullReduce(function (acc, x) { return x ? acc + x : acc + this.default }, '', { default: '-' }))
// ---2-

您可以继续实现其他有用的功能filtereverysome等。

我注意确保它们的行为类似于 forEachmapreduce 对应项;特别是关于更改 lambda 上下文的能力 - 请注意,更改上下文仅适用于非箭头函数,如代码中演示的

那么我们学到了什么?我们使用简单的 for 循环实现了 fullForEachfullReducefullMap 的功能接口(interface)。然而,当函数被调用时,用户就不再需要承担这些细节,并且可以用函数式的风格来表达他们的程序。

关于javascript:带孔数组上的循环函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44925189/

相关文章:

arrays - PDI:同时从 MongoDB 展开两个数组

javascript - ES6模块初始化顺序错误?

javascript - 如何在 Chrome 中将集合转换为数组?

javascript - 为什么要使用 JavaScript 函数声明(和表达式)?

c++ - 为数组中的每个对象调用析构函数

javascript - 在javascript中展平数组以获得最长的字符串

drag-and-drop - Aurelia中的拖放不起作用

javascript - 无法在表中显示数据库中的所有数据

javascript - jQuery 变量对象?

javascript - AngularJS 使用 Ng-Repeat 按属性过滤不工作