将随机对象的关键点设置为其他值

时间:2019-06-19 22:33:47

标签: javascript arrays algorithm object ecmascript-6

我得到一个输入= 5。

我想将此数组中5个随机对象的is_winner键设置为true。

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个for循环的循环,其中之一是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 个答案:

答案 0 :(得分:1)

您还可以考虑像这样使用SetArray.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))

Setwhile负责生成随机数数组(在您的情况下为数组索引)。有了该功能后,您只需通过is_winnertrue设置为Array.forEach

因为函数最好不要改变输入,所以我添加了clone标志,但是如果您不关心它,可以将其删除,也可以删除if(clone)行(仅创建一个克隆)的数组。

答案 1 :(得分:0)

// 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;
    }
};