J'ai un tableau avec 30 valeurs qui seront distribuées aléatoirement entre 3 autres tableaux. Je l'ai fait fonctionner "presque" correctement, mais les 3 tableaux viennent toujours avec une quantité aléatoire d'éléments et j'ai besoin de 2 d'entre eux avec 8 éléments et d'autres avec 14, comment puis-je définir cela?
const arrAll = [s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10] const arrCard = [] const arrCent = [] const arrSec = [] arrAll.map(l => { let rand = Math.floor(Math.random() * 9000) rand <= 3000 ? arrCard.push(l) : rand <= 6000 ? arrCent.push(l) : arrSec.push(l); })
3 Réponses :
Une solution consiste à mélanger le tableau dans son ensemble, puis à sélectionner simplement le nombre d'éléments dans chacun de vos tableaux selon vos besoins.
Voici l'exemple (la fonction de lecture aléatoire a été copiée depuis Comment puis-je mélanger un tableau? )
function shuffle(a) { for (let i = a.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]]; } return a; } function splitArrayRandomly(arr, sizes) { const shuffledArr = shuffle(arr); let pos = 0; const arrays = sizes.map(size => { const newArr = shuffledArr.slice(pos, pos + size); pos += size; return newArr; }); return arrays; } const arr = [4, 7, 15, 22, 11, 6, 19]; // This option create 3 arrays, first of size 4, second of size 2 and last with size 1 const sizes = [4,2,1]; console.log(splitArrayRandomly(arr, sizes));
Dans votre cas, vous mettez dans tailles
ce tableau [8, 8, 14]
et il vous renvoie trois tableaux avec ces tailles. Vous pouvez ensuite les mettre dans vos variables arrCard, arrCent, arrSec
si nécessaire.
tks bro ... je vais essayer ça
1) À partir du tableau d'entrée, créez un ordre aléatoire en générant des index aléatoires en limitant la taille du tableau.
2) Créer un tableau de sortie de tableaux (initialiser) pour la même longueur que le tableau de tailles.
3) maintenez o_idx
(index de sortie) pour suivre quel tableau de sortie aura besoin pour pousser l'élément.
4) Une fois que vous avez obtenu le r_idx
(index aléatoire), puis poussez la valeur correspondante ( arr [r_idx]
) vers le tableau de sortie correspondant ( output [o_idx] code>).
const randomOrderInSizes = (arr, sizes) => {
const myRandom = () => Math.floor((Math.random() * 100) % arr.length);
const temp = [];
const output = sizes.map(() => []);
let o_idx = 0;
arr.forEach(() => {
let r_idx = myRandom();
while (temp.includes(r_idx)) {
r_idx = myRandom();
}
temp.push(r_idx);
if (sizes[o_idx] === output[o_idx].length) {
o_idx += 1;
}
output[o_idx].push(arr[r_idx]);
});
return output;
};
const data = [21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40];
const required = randomOrderInSizes(data, [8, 8, 14]);
console.log(required);
Créez un deuxième tableau qui cartographie la distribution du tableau:
.as-console-row-code { word-break: break-word; overflow-x: hidden; }
Ce serait 3 tableaux - les deux premiers avec la longueur de 8 et le troisième tableau avec la longueur de 14. Dans la démonstration, ce tableau est le deuxième paramètre.
Ensuite, mélangez au hasard le tableau principal. Dans la démo, le tableau principal est le premier paramètre. Pour mélanger au hasard le tableau principal, nous utiliserons le Fisher-Yates Shuffle p >
Enfin, deux boucles for
sont utilisées.
La boucle externe créera un tableau vide. Il itérera la longueur du tableau dist. Dans la démo, ce serait trois fois.
La boucle interne .shift ()
* sortira une valeur du tableau principal (qui a été réorganisée aléatoirement (voir # 2)) puis .push ()
dans le tableau précédemment défini dans la boucle externe (voir # 3.1). Chaque boucle interne itérera le nombre de fois indiqué à la position d'index de l'itération de la boucle externe actuelle.
Exemple (pseudo-code)
const main = ['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's10', 'i1', 'i2', 'i3', 'i4', 'i5', 'i6', 'i7', 'i8', 'i9', 'i10', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'e10']; const dist = [8, 8, 14]; function randomDistribution(array, dist) { let total = array.length, split = dist.length; let result = [], temp, index; while(total) { index = Math.floor(Math.random() * total--); temp = array[total]; array[total] = array[index]; array[index] = temp; } for (let subIdx = 0; subIdx < split; subIdx++) { let subArr = []; for (let reIdx = 0; reIdx < dist[subIdx]; reIdx++) { subArr.push(array.shift()); } result.push(subArr); } return result; } let twoDArray = randomDistribution(main, dist); console.log(JSON.stringify(twoDArray)); const cardArray = twoDArray[0]; const centArray = twoDArray[1]; const sectArray = twoDArray[2]; console.log(`cardArray: ${cardArray}`); console.log(`centArray: ${centArray}`); console.log(`sectArray: ${sectArray}`);
* .shift ()
prendra la valeur d'un tableau à l'index 0 de façon permanente. Ceci est fait pour que les valeurs du tableau principal ne soient pas dupliquées dans les sous-tableaux
Une fois qu'une itération de la boucle interne est terminée, ce tableau sera .push ()
inséré dans le tableau de résultat. Une fois la dernière boucle interne terminée, le tableau de résultat est renvoyé sous forme de tableau à deux dimensions.
Exemple (pseudo-code)
/* Returned as a two dimensional array */ result = [[8 values], [8 values], [14 values]] /* Assign variables to each sub-array */ const cardArr = result[0]; const centArr = result[1]; const sectArr = result[2];
/* On the second iteration of the outer loop, will be 8 */ dist[1] = 8 /* On the inner loop, it will take the values of the randomly reordered main array in the range of 9 thru 16 */ ["e9","i4","i10","s2","e8","i9","i3","i8"]
const dist = [8, 8, 14];