Javascript/angular - 使用forEach向后循环数组

Man*_*023 17 javascript arrays angularjs

有没有办法循环使用数组forEach(不是任何其他类型的循环,我知道如何使用for /标准方法)并且实际上没有反转数组本身?

naa*_*jie 37

var arr = [1, 2, 3];

arr.slice().reverse().forEach(function(x) {
    console.log(x);
})
Run Code Online (Sandbox Code Playgroud)

将打印:

3
2
1
Run Code Online (Sandbox Code Playgroud)

arr仍将是[1, 2, 3],.slice()创造一个浅的副本.

  • 与仅使用 for 循环并向后迭代相比,这是非常低效的。如果 OP 确实需要一个函数,他们可以将 forEachReverse 函数添加到内部使用 for 循环的数组原型上。 (7认同)
  • @kennsorr OP 询问“实际上没有反转数组本身”,并且 .reverse() 修改了调用它的数组实例。.slice() 是一种动态创建数组新副本的快速方法。 (5认同)
  • 请注意,如果您的数组是稀疏的,那么使用reverse将以相反的顺序重新打包数组并破坏我们现有的稀疏索引. (2认同)

tri*_*cot 20

有一个类似的数组方法,它一个反向计数器部分,reducereduceRight

const array = ['alpha', 'beta', 'gamma'];

array.reduceRight((_, elem) => console.log(elem), null);
Run Code Online (Sandbox Code Playgroud)

将其用于请求的目的时,请确保提供第二个参数。它可以是null或其他任何东西。另请注意,回调函数将累加器作为第一个参数,您不需要为此目的。

如果包括一个库是一个选项:

洛达什:forEachRight

  • 唯一不可怕或不明显的答案。好一个。不过,我可能仍然不会在简单的反向 for 循环上使用它 - 太混乱而难以阅读。 (5认同)

Ale*_*x K 13

只需使用 for 循环。从数组的末尾开始,然后从那里向后。

const array = ['blastoff', 1, 2, 3];

for (let index = array.length - 1; index >= 0; index--) {
  const element = array[index];
  console.log(element);
}
Run Code Online (Sandbox Code Playgroud)

  • 哦...阅读其他答案后我对开发人员失去了信心,但这就是正确且有效的解决方案 (10认同)
  • 引用问题:“不是任何其他类型的循环,我知道如何使用 for / 标准方法”,这个答案是不合适的。 (4认同)
  • 我认为提问者正在寻找他们希望存在的某种标准“forEachReverse()”。他们问题的真正答案是“抱歉,它不存在”。 (4认同)
  • @Guntram这是最快的方法。我能想到的不使用 for 循环来实现此目的的唯一原因是提出问题的人试图在他们的计算机作业上作弊。:D (2认同)

T.J*_*der 9

不,forEach只有进程通过阵列前进.所以你必须做一些别的事情,你在问题中说过的事情超出了范围.

我可以想到两个只使用前体来使用的选项forEach(因此,它们不使用for循环或其他类型的循环).我不知道那些是否超出范围,所以这里是:

  1. 复制数组并反转副本,然后使用forEach

  2. 使用Object.keys来获取指标,扭转,然后使用forEach它(将通过该指标,而不是价值循环,但我们可以查找.)

这是#1:

slice复制数组(浅拷贝,所以不太可能是昂贵的),然后我们反转它,然后forEach:

var a = ['one', 'two', 'three'];
a.slice().reverse().forEach(function(entry) {
    snippet.log(entry);
});
snippet.log("Proof that a is not, itself, reversed: " +
            JSON.stringify(a));
Run Code Online (Sandbox Code Playgroud)
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Run Code Online (Sandbox Code Playgroud)

这是#2:

我们用Object.keys得到数组索引(使用filter,如果你保存在你的阵列非元素属性),反,然后在结果循环:

var a = ['one', 'two', 'three'];
Object.keys(a).reverse().forEach(function(index) {
    snippet.log(a[index]);
});
snippet.log("Proof that a is not, itself, reversed: " +
            JSON.stringify(a));
Run Code Online (Sandbox Code Playgroud)
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Run Code Online (Sandbox Code Playgroud)


旁注:filter如果你的数组中有非元素属性,这就是我的意思:

var a = ['one', 'two', 'three'];
a.nonElementProperty = "foo";
Object.keys(a).filter(function(name) {
  return String(+name) === name;
}).reverse().forEach(function(index) {
    snippet.log(a[index]);
});
snippet.log("Proof that a is not, itself, reversed: " +
            JSON.stringify(a));
Run Code Online (Sandbox Code Playgroud)
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Run Code Online (Sandbox Code Playgroud)


Bli*_*n67 6

到目前为止,浏览器似乎还没有优化该Array.forEach功能。不费吹灰之力,您就可以编写一个简单的 polyfill,Array.forEach以至少 10 比 1执行该方法。

因此,您可以创建自己的Array.revEach并使其性能优于本机Array.forEach,我希望浏览器能Array.forEach尽快解决性能非常慢的问题,并且不需要对现有的实际方法进行 polyfill。

对于Array.revEach出进行Array.forEach中的“铬46.0.2490.22的β-米”运行17倍的速度

if (Array.prototype.revEach === undefined) { 
    Object.defineProperty(Array.prototype, 'revEach', { 
        writable : false,
        enumerable : false,
        configurable : false,
        value : function (func) {
            var i;
            var len = this.length-1;
            for (i = len; i >= 0; i--) {
                func(this[i], i, this);
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

只是为了添加实际的官方 polyfill 修改为反向。评论显示了我的变化。

// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.io/#x15.4.4.18
// Modified by Blindman67 to revEach
if (!Array.prototype.revEach) {   // name changed
  Array.prototype.revEach = function(callback, thisArg) { // name changed
    var T;  // k defined where len was
    if (this == null) {
      throw new TypeError(' this is null or not defined');
    }
    var O = Object(this);
    var k = (O.length >>> 0)-1;  // set k (counter) ToUint32
                                 // len var removed
    if (typeof callback !== "function") {
      throw new TypeError(callback + ' is not a function');
    }
    if (arguments.length > 1) {
      T = thisArg;
    }
    while (k >= 0) {  // reverse condition
      var kValue;
      if (k in O) {
        kValue = O[k];
        callback.call(T, kValue, k, O);
      }
      k--;  // dec counter
    }
  };
}
Run Code Online (Sandbox Code Playgroud)


Joh*_*ohn 5

可以使用反向方法,forEach方法和(如果使用ES6)箭头功能相对简洁地完成此操作

var someArray = ["a","b","c","d"];
someArray.reverse().forEach(arrayItem =>
    console.log(arrayItem)
)
Run Code Online (Sandbox Code Playgroud)

如果您不使用ES6,则解决方案大致相同,只是没有箭头功能。

var someArray = ["a","b","c","d"];
someArray.reverse().forEach(function(arrayItem) {
    console.log(arrayItem)
})
Run Code Online (Sandbox Code Playgroud)

两者都将打印到控制台:

d
c    
b
a
Run Code Online (Sandbox Code Playgroud)

  • 实际上`.reverse()` 会反转`someArray`,所以你需要再次执行`someArray.reverse()` 否则它会导致不受欢迎的错误。 (2认同)
  • @V.Dalechyn 两个 `reverse()` 并不构成正确!这是一个糟糕的答案。 (2认同)

gra*_*bag 5

array.forEach 有 3 个参数。您可以使用这些来有效地向后移动 forEach。

var arr = [1, 2, 3];

    arr.forEach(function(x, index, the_array) {
        let x_prime = the_array[the_array.length-1-index]
        console.log(x_prime);
    })
Run Code Online (Sandbox Code Playgroud)

将打印

3
2
1
Run Code Online (Sandbox Code Playgroud)

  • 这只是执行正常“for”循环的一种非常复杂的方式。 (5认同)