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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32682962/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:04:47  来源:igfitidea点击:

Javascript / angular - Loop through array backwards with forEach

javascriptarraysangularjs

提问by Mankind1023

Is there a way to loop backwards through an array using forEach(not any other kind of loop, I know how to do with with a for / standard ways) and without actually reversing the array itself?

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

回答by naartjie

var arr = [1, 2, 3];

arr.slice().reverse().forEach(function(x) {
    console.log(x);
})

will print:

将打印:

3
2
1

arrwill still be [1, 2, 3], the .slice()creates a shallow copy.

arr仍然会[1, 2, 3].slice()创建一个浅拷贝。

回答by T.J. Crowder

No, forEachonly processes forward through the array. So you'd have to do something else, which you've said in your question was out of scope.

不,forEach只能通过阵列向前处理。所以你必须做一些其他的事情,你在问题中说这超出了范围。

I can think of two options which just use precursorsto using forEach(so, they don't use a forloop or other kind of loop). I don't know if those would be out of scope or not, so here they are:

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

  1. Copy the array and reverse the copy, then use forEachon it

  2. Use Object.keysto get the indexes, reverse that, then use forEachon it (which will loop through the indexes, not the values, but then we can look them up)

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

  2. 使用Object.keys得到的指标,扭转,然后使用forEach它(它通过索引将循环,而不是价值,但我们可以查找。)

Here's #1:

这是#1:

slicecopies the array (shallow copy, so not likely to be expensive), then we reverse it, then forEach:

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));
<!-- 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>

Here's #2:

这是#2:

We use Object.keysto get the array indices (using filterif you store non-element properties in your arrays), reverse that, and then loop through the result:

我们用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));
<!-- 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>



Side note: Here's what I mean about using filterif you have non-element properties on your array:

旁注: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));
<!-- 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>

回答by trincot

There is a similar array method that hasa reverse counter part, reducecomes together with reduceRight:

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

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

array.reduceRight((_, elem) => console.log(elem), null);

When using it for the requested purpose, make sure to provide a second argument. It can be nullor anything else. Also note that the callback function has as first argument the accumulator, which you don't need for this purpose.

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

If including a library is an option:

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

Lodash: forEachRight.

洛达什:forEachRight

回答by John

This can be accomplished relatively concisely using the reversemethod, the forEachmethod, and (if using ES6) the arrowfunction

这可以使用reverse方法、forEach方法和(如果使用 ES6)箭头函数相对简洁地完成

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

If you are not using ES6, the solution is about the same, just without the arrow function.

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

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

Both will print to the console:

两者都将打印到控制台:

d
c    
b
a

回答by grabbag

array.forEach has 3 parameters. You can use these to effectively forEach backward.

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);
    })

will print

将打印

3
2
1

回答by Alex K

Just use a for loop. Start at the end of the array and go backwards from there.

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

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

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

回答by Blindman67

As yet the browsers do not seem to have optimised the Array.forEachfunction. With not much effort you can write a simple polyfill that out performs the Array.forEachmethod by at least 10 to 1.

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

So you can create your own Array.revEachand have it outperform the native Array.forEach, thought I hope that the browsers address the very slow performance of Array.forEachsoon and make the need to polyfill actual existing methods not necessary.

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

For Array.revEachout performs Array.forEachrunning 17 times faster on "Chrome 46.0.2490.22 beta-m"

对于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);
            }
        }
    });
}

Just to add the actual official polyfill modified to reverse. Comments show my changes.

只是为了添加实际的官方 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
    }
  };
}