Javascript 将带有重复项的数字数组转换为唯一的数字集

Javascript convert array of numbers with duplicates into unique sets of numbers

本文关键字:数字 转换 数组 唯一 Javascript      更新时间:2023-09-26

我有一个JavaScript排序算法问题,我正在努力有效地解决。

有一个数字数组,我称之为卡,例如 [1,2,3,4,5,6,7,8,9,10]每天我有6套教学。在每组中,我想显示最多5张随机和独特的卡片。每张卡片每天必须显示 3 次

到目前为止,我所做的是创建 6 个空数组(集合)。然后,我遍历我的卡片 3 次,每次尝试将它们添加到随机集合中,如果该卡在该数组中尚不存在。有时它可以工作,但大多数时候我遇到一个问题,我只有一个剩余空间的数组,而该数组已经包含卡。我的代码:

在我的代码中假设 numberOfSetsPerCard = 3 & totalSets = 6。唯一可用的库是 JQuery。

shuffleIntoSets : function(cards, numberOfSetsPerCard, totalSets) {
        var sets = [];
        // initialize the sets as empty arrays
        for (i = 0; i < totalSets; i++) {
            sets[i] = [];
        }

        $.each(cards, function(index, card) {
            for(x=0;x<numberOfSetsPerCard;) {
                // attempt to place the card in a set which doesnt already contain the card
                setNo = Math.floor((Math.random() * totalSets));
                console.log("setNo: " + setNo);
                if(jQuery.inArray(card,sets[setNo]) == -1 && sets[setNo].length<5) {
                    console.log(setNo + "does not contain: " + card);
                    sets[setNo].push(card);
                    console.log("Added the card, set now looks like :" + sets[setNo]);
                    x++;
                }
            }
        });
        return sets;
    },

这是我对您的问题的解决方案,它有点长,但我认为它有点长,但它肯定会在教学集中产生随机性,并满足您所说的条件

代码笔链接:http://codepen.io/anon/pen/yyoaZy

html/include jquery:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

.js:

//-----------------------------------------------
//For this question on StackOverflow:
//http://stackoverflow.com/questions/28192127/javascript-convert-array-of-numbers-with-duplicates-into-unique-sets-of-numbers
//-----------------------------------------------
var cards = [1,2,3,4,5,6,7,8,9,10];
var numOfTeachingSets = 6;
var numOfUniqueCardsPerTeachingSet = 5;
var numOfCardRepetitionPerDay = 3;

var shuffleCards = function(cards, numOfTeachingSets, numOfUniqueCardsPerTeachingSet, numOfRepetitionPerCard){
  if(cards.length*numOfRepetitionPerCard != numOfTeachingSets*numOfUniqueCardsPerTeachingSet){
    alert("invalid param");
    return null;
  }
  //since each card is required to repeat numOfRepetitionPerCard times
  //the available choices should be numOfRepetitionPerCard times of the original deck of cards
  var availableCardChoices = cards.concat([]);
  for (var i=0;i<numOfRepetitionPerCard-1;i++){
    availableCardChoices = availableCardChoices.concat(cards);
  }
  //Record down items from [availableCardChoices] has been picked
  var choosenList = [];
  //Put 6 sets of unique cards into the result
  var result = [];
  for (var i=0;i<numOfTeachingSets;i++){
    result.push( pickOutUniqueNumberSet(availableCardChoices,numOfUniqueCardsPerTeachingSet, choosenList) );
  }
  //return the result - an array of [numOfTeachingSets] arrays
  return result;
}
//-----------------------------------------------------------
// Function:
// picks [cardsPerSet] number of unique item out of [availableChoices]
// each time an item is picked, this item is removed from [availableChoices]
//
// Important note:  The number of card repetition is not really meaningful
//                  because if each round of picking produces unique sets,
//                  then the number of card repetition condition will be
//                  automatically satisfied.
//-----------------------------------------------------------
var pickOutUniqueNumberSet = function(availableChoices, cardsPerSet, disabledChoices){
  if (cardsPerSet==0 || availableChoices.length==0){
    return null;
  }
  var choosenSet = [];
  var maxAttempts = 10000;  //these 2 counter are used to prevent infinite looping
  var attempts = 0;
  for(var i=0;i<cardsPerSet;i++){
    //items are choosen from [availableChoices] by their array index.
    var randomIndex = Math.floor((Math.random() * availableChoices.length));
    //repeatedly grab a random index from availableChoices till a unique one is selected
    //unique item is an item that is not repeated in choosenSet, and its index is not in disabledChoices
    while( (InArray(choosenSet, availableChoices[randomIndex]) || InArray(disabledChoices, randomIndex)) && attempts<maxAttempts){
      randomIndex = Math.floor((Math.random() * availableChoices.length));
      attempts++;
    }
    //Add this item to the chooseSet
    choosenSet.push(availableChoices[randomIndex]);
    //Add this item's index to disabledChoices
    disabledChoices.push(randomIndex);
  }
  return choosenSet;
}
var InArray = function(array, itemToFind){
  for(var i=0;i<array.length; i++){
    if(array[i]==itemToFind){
      return true;
    }
  }
  return false;
}

//---------- Test --------
var teachingSets = shuffleCards(cards, numOfTeachingSets, numOfUniqueCardsPerTeachingSet, numOfCardRepetitionPerDay);
for(var i=0;i<teachingSets.length; i++){
  document.write(teachingSets[i] + "<br>");
}