首页 > 解决方案 > 为每个用户随机分配至少一个唯一项,不重复

问题描述

为每个用户随机分配至少一个唯一项目。例如,如果 5 个项目和 5 个用户,每个用户获得 1 个项目。如果 4 个项目和 5 个用户,则只有 4 个用户每人获得 1 个项目。如果 7 个项目和 4 个用户,则 3 个用户每人得到 2 个项目,1 个用户得到 1 个项目,依此类推。下面的脚本旨在实现这一目标,但得到了错误的结果。

  assignItemsToUsers() {

let items = [
  {
    id: 1,
    name: "item1",
    tag: 1900
  },
  {
    id: 2,
    name: "item2",
    tag: 1876
  },
  {
    id: 3,
    name: "item3",
    tag: 1575
  },
  {
    id: 4,
    name: "item4",
    tag: 4783
  },
  {
    id: 5,
    name: "item5",
    tag: 67894
  },
  {
    id: 6,
    name: "item6",
    tag: 66789
  },
  {
    id: 7,
    name: "item7",
    tag: 67890
  },
  {
    id: 8,
    name: "item8",
    tag: 87654
  },
  {
    id: 9,
    name: "item9",
    tag: 94948
  }
];


let users = [
  {
    id: 1,
    name: "user1",
    userID: 38494
  },
  {
    id: 2,
    name: "user2",
    userID: 84844
  },
  {
    id: 3,
    name: "user3",
    userID: 47483
  },
  {
    id: 4,
    name: "user4",
    userID: 83735
  }
];


let results = [];
            let tempResults = [];

            for (let i = 0; i < items.length; i++) {

                const item = items[i];

                const randomUser = users[Math.floor(Math.random() * users.length)];//pick user at random

                randomUser.tempitem = item;//asign item to this user
                tempResults.push(randomUser);//push to tempResults

            }

            //Group assigned items to their respective user
            for (let i = 0; i < users.length; i++) {
                const user = users[i];

                let myluckyitems = [];
                for (let index = 0; index < tempResults.length; index++) {
                    //check where tempResults[index].id == user.id
                    const assigneduser = tempResults[index];

                    if (user.id == assigneduser.id) {
                        //True: this was the assigned user.
                        myluckyitems.push(assigneduser.tempitem);
                    }

                }

                //all items assigned, then append to user object & push to results
                if (myluckyitems.length > 0) {
                    user.items = myluckyitems;
                    results.push(user);
                }

            }
            console.log(results);
}

实际结果

 results = [
                {
                    id: 1,
                    name: user1,
                    userID: 38494,
                    items: [
                        {
                            id: 1,
                            name: item1,
                            tag: 1900
                        },
                        {
                            id: 1,
                            name: item1,
                            tag: 1900
                        }
                    ],

                    tempitem: {
                        id: 1,
                        name: item1,
                        tag: 1900
                    },

                },

                {
                    id: 2,
                    name: user2,
                    userID: 84844,
                    items: [
                        {
                            id: 2,
                            name: item2,
                            tag: 1876
                        },
                        {
                            id: 2,
                            name: item2,
                            tag: 1876
                        },
                        {
                            id: 2,
                            name: item2,
                            tag: 1876
                        },
                    ],

                    tempitem: {
                        id: 2,
                        name: item2,
                        tag: 1876
                    },
                },
                {
                    id: 3,
                    name: user3,
                    userID: 47483,
                    items: [
                        {
                            id: 3,
                            name: item3,
                            tag: 1575
                        },
                        {
                            id: 3,
                            name: item3,
                            tag: 1575
                        }
                    ],

                    tempitem: {
                        id: 3,
                        name: item3,
                        tag: 1575
                    },
                },
                {
                    id: 4,
                    name: user4,
                    userID: 83735,
                    items: [
                        {
                            id: 4,
                            name: item4,
                            tag: 4783
                        },
                        {
                            id: 4,
                            name: item4,
                            tag: 4783
                        }
                    ],

                    tempitem: {
                        id: 4,
                        name: item4,
                        tag: 4783
                    },
                }
            ];

预期成绩

results = [
                {
                    id: 1,
                    name: user1,
                    userID: 38494,
                    items: [
                        {
                            id: 1,
                            name: item1,
                            tag: 1900
                        },
                        {
                            id: 5,
                            name: item5,
                            tag: 67894
                        },
                        {
                            id: 9,
                            name: item9,
                            tag: 94948
                        }
                    ],
                },

                {
                    id: 2,
                    name: user2,
                    userID: 84844,
                    items: [
                        {
                            id: 2,
                            name: item2,
                            tag: 1876
                        },
                        {
                            id: 6,
                            name: item6,
                            tag: 66789
                        },


                    ],
                },
                {
                    id: 3,
                    name: user3,
                    userID: 47483,
                    items: [
                        {
                            id: 3,
                            name: item3,
                            tag: 1575
                        },
                        {
                            id: 7,
                            name: item7,
                            tag: 67890
                        },
                    ],
                },
                {
                    id: 4,
                    name: user4,
                    userID: 83735,
                    items: [
                        {
                            id: 4,
                            name: item4,
                            tag: 4783
                        },
                        {
                            id: 8,
                            name: item8,
                            tag: 87654
                        },
                    ],
                }
            ];

不同之处在于,实际结果为每个用户返回重复的项目,并不是所有项目都分配给用户,它还将tempitem属性附加到每个用户,这是不需要的。

预期结果,将唯一的项目分配给每个用户而不重复,并确保必须将项目分配给用户。

标签: javascript

解决方案


function shuffleArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
  return array;
}

function assign() {
  const itemsLength = items.length;
  for (var i=itemsLength+1, shuffledArray=[]; i--;) shuffledArray.push(i);
  shuffledArray = shuffleArray(shuffledArray);
  
  const eachUserItems = itemsLength/users.length;
  
  Object.entries(users).map(([key, value]) => {
      for(i = 0; i < Math.round(eachUserItems); i++) {
        users[key]['items'] = users[key]['items'] || [];
        var popNewIndex = shuffledArray.pop();
        var objectToInsert = items.find((i) => i.id == popNewIndex + 1);
        users[key]['items'].push(objectToInsert);
      }
  });  
  
  return users;
}

这将为您提供始终随机分配给用户的预期项目

附言。

这里还有一个简单的想法是,我们不会在每个循环上随机化,而是制作一个随机值列表,我们将一个一个地弹出。我们可以使用随机值通过 id 从列表中获取值并分配它。由于列表应该具有随机的唯一值,因此它可以确保没有值再次分配给任何其他用户。


推荐阅读