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
Javascript / angular - Loop through array backwards with forEach
提问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
arr
will still be [1, 2, 3]
, the .slice()
creates a shallow copy.
arr
仍然会[1, 2, 3]
,.slice()
创建一个浅拷贝。
回答by T.J. Crowder
No, forEach
only 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 for
loop or other kind of loop). I don't know if those would be out of scope or not, so here they are:
我可以想到两个选项,它们只使用前体来使用forEach
(因此,它们不使用for
循环或其他类型的循环)。我不知道这些是否超出范围,所以它们是:
Copy the array and reverse the copy, then use
forEach
on itUse
Object.keys
to get the indexes, reverse that, then useforEach
on it (which will loop through the indexes, not the values, but then we can look them up)
复制数组并反转副本,然后
forEach
在其上使用使用
Object.keys
得到的指标,扭转,然后使用forEach
它(它通过索引将循环,而不是价值,但我们可以查找。)
Here's #1:
这是#1:
slice
copies 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.keys
to get the array indices (using filter
if 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 filter
if 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, reduce
comes together with reduceRight
:
有一个类似的数组方法,它有一个反向计数器部分,reduce
与reduceRight
:
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 null
or 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.forEach
function. With not much effort you can write a simple polyfill that out performs the Array.forEach
method by at least 10 to 1.
到目前为止,浏览器似乎还没有优化该Array.forEach
功能。不费吹灰之力,您就可以编写一个简单的 polyfill,Array.forEach
以至少 10 比 1执行该方法。
So you can create your own Array.revEach
and have it outperform the native Array.forEach
, thought I hope that the browsers address the very slow performance of Array.forEach
soon and make the need to polyfill actual existing methods not necessary.
因此,您可以创建自己的Array.revEach
并使其性能优于本机Array.forEach
,我希望浏览器能Array.forEach
尽快解决性能非常慢的问题,并且不需要对现有的实际方法进行 polyfill。
For Array.revEach
out performs Array.forEach
running 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
}
};
}