Existe-t-il un moyen de revenir en arrière dans un tableau en utilisant forEach
(pas n'importe quel autre type de boucle, je sais faire avec des méthodes for/standard) et sans inverser le tableau lui-même?
var arr = [1, 2, 3];
arr.slice().reverse().forEach(function(x) {
console.log(x);
})
imprimera:
3
2
1
arr
sera toujours [1, 2, 3]
, la .slice()
crée une copie superficielle.
Non, forEach
ne traite que les processus en avant dans le tableau. Il faudrait donc faire autre chose, ce que vous avez dit dans votre question était hors de portée.
Je peux penser à deux options qui utilisent simplement precursors à utiliser forEach
(ainsi, ils n’utilisent pas de boucle for
ou un autre type de boucle). Je ne sais pas si ceux-ci seraient hors de portée ou non, alors les voici:
Copiez le tableau et inversez la copie, puis utilisez forEach
dessus
Utilisez Object.keys
pour obtenir les index, inversez-le, puis utilisez forEach
dessus (qui parcourt les index, pas les valeurs, mais nous pouvons les rechercher)
Voici # 1:
slice
copie le tableau (copie superficielle, donc peu coûteuse), puis nous l'inversons, puis 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>
Voici # 2:
Nous utilisons Object.keys
pour obtenir les index de tableau (en utilisant filter
si vous stockez des propriétés non-élément dans vos tableaux), inversez que , puis parcourez le résultat:
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>
Note latérale: Voici ce que je veux dire à propos de l'utilisation de filter
si vous avez des propriétés non-élément sur votre tableau:
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>
Ceci peut être accompli de manière relativement concise en utilisant la méthode reverse , la méthode forEach et (si vous utilisez ES6) la flèche
var someArray = ["a","b","c","d"];
someArray.reverse().forEach(arrayItem =>
console.log(arrayItem)
)
Si vous n'utilisez pas ES6, la solution est à peu près la même, mais sans la fonction de flèche.
var someArray = ["a","b","c","d"];
someArray.reverse().forEach(function(arrayItem) {
console.log(arrayItem)
})
Les deux vont imprimer sur la console:
d
c
b
a
Les navigateurs ne semblent pas encore avoir optimisé la fonction Array.forEach
. Avec peu d'effort, vous pouvez écrire un simple polyfill qui exécute la méthode Array.forEach
d'au moins 10 à 1.
Vous pouvez donc créer votre propre Array.revEach
et le surpasser par rapport au Array.forEach
natif, mais je espère que les navigateurs s’attaqueront bientôt à la très lente performance de Array.forEach
et rendront inutile la nécessité de polyfiler les méthodes existantes.
For Array.revEach
out exécute Array.forEach
17 fois plus rapidement sur "Chrome 46.0.2490.22 beta-m"
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);
}
}
});
}
Juste pour ajouter le polyfill officiel réel modifié pour inverser. Les commentaires montrent mes modifications.
// 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
}
};
}
Il existe une méthode de tableau similaire qui a une partie de compteur inverse, reduce
est associé à reduceRight
:
const array = ['alpha', 'beta', 'gamma'];
array.reduceRight((_, elem) => console.log(elem), null);
Lorsque vous l'utilisez aux fins demandées, assurez-vous de fournir un deuxième argument. Cela peut être null
ou autre chose. Notez également que la fonction de rappel a pour premier argument l'accumulateur, dont vous n'avez pas besoin pour cela.
Si inclure une bibliothèque est une option:
Lodash: forEachRight
.
Utilisez simplement une boucle for. Commencez à la fin du tableau et reculez à partir de là.
const array = ['blastoff', 1, 2, 3];
for (let index = array.length - 1; index >= 0; index--) {
const element = array[index];
console.log(element);
}
array.forEach a 3 paramètres. Vous pouvez les utiliser efficacement pour chaque en arrière.
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);
})
imprimera
3
2
1