I saw that this method you are using to "shuffle" the array, is not very indicated, see this post from the English OS:
https://stackoverflow.com/a/18650169/8133067
[community Edit: This Answer is incorrect; see comments. It is being left here for Future Reference because the idea is not that Rare.]
[1,2,3,4,5,6].sort(function() {
return .5 - Math.random();
});
I then got another answer to that same question in the English OS:
How to Randomize (shuffle) a Javascript array?
https://stackoverflow.com/a/2450976/8133067
To set up this function:
function shuffle(array) {
var currentIndex = array.length;
var newArray = array.slice();
var temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = newArray[currentIndex];
newArray[currentIndex] = newArray[randomIndex];
newArray[randomIndex] = temporaryValue;
}
return newArray;
}
I also created this other function:
function getPessoaSorteada(pessoas, pessoasSorteadas) {
if (pessoasSorteadas.length == 0)
pessoasSorteadas = shuffle(pessoas);
return pessoasSorteadas.pop();
}
And I modified that part of your code where the Result is assembled, so:
var pessoasSorteadas = [];
var pessoa1, pessoa2;
datas.forEach(data => {
pessoa1 = getPessoaSorteada(Pessoa, pessoasSorteadas);
pessoa2 = getPessoaSorteada(Pessoa, pessoasSorteadas);
if (pessoa2==pessoa1)
pessoa2 = getPessoaSorteada(Pessoa, pessoasSorteadas);
Resultado.push({
data: data.format('L'),
diaSemana: semana[data.day()],
escala: [pessoa1, pessoa2]
})
});
Explaining:
I create a copy of the people and shuffle array, to make the draw. Every day I want, I use two people from that list and remove them from there, when the list (array) runs out of people, I create a scrambled copy of the list of people again. I only check to make sure that the last person on the previous list is the same as the first person on the current list.
That way I think the result turned out the way you wanted. That’s what it was?
EDIT:
I realized that there was a hole in my first suggestion: if, by coincidence, it happened to the last person drawn from a round to be equal to the first person used from the list in the next round, I would simply ignore that person and use the next one on the list, so there would be no repetition, but then this person would not be climbed in this next round, ie would be a round of 6 people only, instead of 7.
I thought of a new scheme, so in the case of repetition, instead of skipping the person, I recreate the draw list as many times as necessary until the last person doesn’t repeat himself. That way, I’ll always have a complete list, with all seven people, and no "double" anyone.
For that, I changed this function:
function getPessoaSorteada(pessoas, pessoasSorteadas, ultimaPessoaSorteada) {
if (pessoasSorteadas.length == 0) {
pessoasSorteadas = shuffle(pessoas);
while (ultimaPessoaSorteada == pessoasSorteadas[pessoasSorteadas.length - 1])
pessoasSorteadas = shuffle(pessoas);
}
return pessoasSorteadas.pop();
}
And I also changed the section that assembles the result:
var pessoasSorteadas = [];
var pessoa1, pessoa2;
datas.forEach(data => {
pessoa1 = getPessoaSorteada(Pessoa, pessoasSorteadas, pessoa2);
pessoa2 = getPessoaSorteada(Pessoa, pessoasSorteadas, pessoa1);
Resultado.push({
data: data.format('L'),
diaSemana: semana[data.day()],
escala: [pessoa1, pessoa2]
})
});
EDIT 2:
There was another problem in the code I proposed: The function getPessoaSorteada()
recreated the array pessoasSorteadas
when it was empty, but in Javascript apparently there is no way to pass an argument by reference (by ref), then, when I recreated the array within the function, it was not returned to the code that called the function, so the array was being recreated all the time, causing several repetitions in the people selected:
function getPessoaSorteada(pessoas, pessoasSorteadas, ultimaPessoaSorteada) {
// ...
// Essa linha criava um novo array, que não era
// devolvido através do argumento da função.
pessoasSorteadas = shuffle(pessoas);
// ...
}
I had found it strange because when I tested the code it worked, but then I discovered also why before it worked: I had misspelled the function parameter name, I wrote pesoasSorteadas
(with a’s' only), but in the body of the function I was using the correct name, pessoasSorteadas
. How the code variable that called the function also had the same name, pessoasSorteadas
, and was in a "global" scope, I think he was using within the function the variable that was defined outside of it.
The solution I found was to fill the array passed as argument to the function with the values of the new array, so the array is returned by the argument, since it is not recreated, and therefore remains the same object. For this I used as a basis this answer in ONLYen, then the passage that used to be like this:
function getPessoaSorteada(pessoas, pessoasSorteadas, ultimaPessoaSorteada) {
// ...
// Essa linha criava um novo array, que não era
// devolvido através do argumento da função.
pessoasSorteadas = shuffle(pessoas);
// ...
}
now it’s like this:
function getPessoaSorteada(pessoas, pessoasSorteadas, ultimaPessoaSorteada) {
// ...
// Agora ao invés de criar um novo array em cima do argumento
// 'pessoasSorteadas', o mesmo objeto (array) passado para a
// função é populado com os elementos do novo array, com as
// pessoas sorteadas, criado pela função shuffle(pessoas).
pessoasSorteadas.push.apply(sorteadas, shuffle(pessoas));
// ...
}
The whole function went like this, so:
function getPessoaSorteada(pessoas, pessoasSorteadas, ultimaPessoaSorteada) {
if (pessoasSorteadas.length == 0) {
pessoasSorteadas.push.apply(pessoasSorteadas, shuffle(pessoas));
while (ultimaPessoaSorteada == pessoasSorteadas[pessoasSorteadas.length - 1])
pessoasSorteadas.push.apply(pessoasSorteadas, shuffle(pessoas));
}
return pessoasSorteadas.pop();
}
Still he’s the same people next
03/04/2018 - Fulano 1 / Fulano 2 03/08/2018 - Fulano 1 / Fulano 2
... https://stackblitz.com/edit/js-qkkbxg?file=index.html– NoobSaibot
Weird, yesterday when I tested it was working fine, now there really is something wrong,.
– Pedro Gaspar
I discovered the problem, and because yesterday worked, I will edit the answer (EDIT 2).
– Pedro Gaspar
And now it’s worked?
– Pedro Gaspar