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

时间:2015-01-28 12:20:42

标签: javascript jquery arrays sorting

我有一个javascript排序算法问题,我正在努力解决这个问题。

我有一系列数字,我正在拨打电话卡,例如[1,2,3,4,5,6,7,8,9,10] 每天我都有 6套教学。在每组中我想显示最多5 RANDOM&独一无二的卡。每张卡必须每天正好显示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;
    },

1 个答案:

答案 0 :(得分:0)

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

codepen link: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>");
}