function choose(arr, size) {
var allResult = [];
(function (arr, size, result) {
var arrLen = arr.length;
if (size > arrLen) {
return;
}
if (size == arrLen) {
allResult.push([].concat(result, arr))
} else {
for (var i = 0; i < arrLen; i++) {
var newResult = [].concat(result);
newResult.push(arr[i]);
if (size == 1) {
allResult.push(newResult);
} else {
var newArr = [].concat(arr);
newArr.splice(0, i + 1);
arguments.callee(newArr, size - 1, newResult);
}
}
}
})(arr, size, []);
return allResult;
}
Il s'agit d'une implémentation de permutation et de combinaison utilisant la magie noire. Les fonctions obtenues sont en gros :
choose([1, 2, 3], 1) obtient
[ [ 1 ], [ 2 ], [ 3 ] ]
choose([1, 2, 3], 2) obtient
[ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ] ]
choose([1, 2, 3, 4], 3) obtient
[ [ 1, 2, 3 ], [ 1, 2, 4 ], [ 1, 3, 4 ], [ 2, 3, 4 ] ]
La fonction anonyme interne s'appelle récursivement via
arguments.callee
. Chaque fois qu'elle s'appelle récursivement, le paramètre size est réduit de un. Chaque newResult est un résultat bidimensionnel [la longueur est le nombre total de combinaisons et chaque élément est la combinaison actuelle]. Tableau, lorsque la longueur de chaque élément de newResult atteint la taille, la récursion se termine et le résultat final est renvoyé.La méthode d'écriture de fermeture empêche les paramètres internes de la fonction d'être affectés par des facteurs externes.