Установить ключ случайных объектов на другое значение - PullRequest
0 голосов
/ 20 июня 2019

Мне дают ввод = 5.

Я хочу установить для ключа is_winner значение true для 5 случайных объектов в этом массиве.

const participants = [
    {code: '111111', is_winner: false},
    {code: '222222', is_winner: false},
    {code: '444444', is_winner: false},
    {code: '777777', is_winner: false},
    {code: '555555', is_winner: false},
    {code: '666666', is_winner: false},
    {code: '333333', is_winner: false},
    {code: '888888', is_winner: false},
    {code: '999999', is_winner: false},
];

Первая рандомизация:

const participants = [
    {code: '111111', is_winner: false},
    {code: '222222', is_winner: true},
    {code: '444444', is_winner: false},
    {code: '777777', is_winner: true},
    {code: '555555', is_winner: false},
    {code: '666666', is_winner: true},
    {code: '333333', is_winner: true},
    {code: '888888', is_winner: false},
    {code: '999999', is_winner: true},
];

Я попробовал следующее, у которого есть 2 для циклов, и один из них - O (n ^ 2)

const winners = [];

while (winners.length < 5) {
    const randomParticipant = participants[Math.floor(Math.random() * participants.length)];

    if (!winners.includes(randomParticipant.code)) {
        winners.push(randomParticipant.code);
    }
}

for (let participant of participants) {
    if (winners.includes(participant.code)) {
        participant.is_winner = true;
    }
}

Проверка, есть ли что-то более эффективное.

Ответы [ 2 ]

1 голос
/ 20 июня 2019

Вы также можете рассмотреть возможность сделать это с Set и Array.forEach , например:

const participants = [ {code: '111111', is_winner: false}, {code: '222222', is_winner: false}, {code: '444444', is_winner: false}, {code: '777777', is_winner: false}, {code: '555555', is_winner: false}, {code: '666666', is_winner: false}, {code: '333333', is_winner: false}, {code: '888888', is_winner: false}, {code: '999999', is_winner: false}, ];

let randomize = (arr, n=5, clone=true) => {
  let set = new Set(), _arr = arr
  if(clone) _arr = arr.map(x => ({...x})) // skip if you want to mutate
  while(set.size < n) set.add(Math.floor(Math.random() * participants.length))
  Array.from(set).forEach(x => _arr[x].is_winner = true)
  return _arr
}

console.log(randomize(participants))
console.log(randomize(participants, 3))

Set и while заботятся о генерации массива случайных чисел (в вашем случае индексы массива). Если у вас есть это, вы просто устанавливаете is_winner на true через Array.forEach.

Поскольку для функций предпочтительно не изменять входные данные, я добавил флаг clone, но если вам это не важно, вы можете удалить его, а также строку if(clone), которая просто создает клон массива.

0 голосов
/ 20 июня 2019
// Found a nice way to shuffle in this SOF post https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array
const shuffle = (array) => {
    for (let i = array.length - 1; i > 0; i--) {
        let j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
    return array
};

// Selects random participants and set their is_winner key to true.
const setRandomWinners = (numberOfWinners) => {
    const arr = [...Array(participants.length).keys()];
    const shuffledArr = shuffle(arr);
    const newArr = shuffledArr.slice(0, numberOfWinners);

    for (let el of newArr) {
        participants[el].is_winner = true;
    }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...