【问题标题】:Is it possible to shuffle objects around within and between an array of arrays?是否可以在数组数组内和数组之间随机播放对象?
【发布时间】:2013-02-22 21:05:49
【问题描述】:

假设我在 javascript 中有一个数组,例如

[[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18]]

我可以随机打乱子数组的元素以获得类似的东西

[[16,4,10],[8,3,9],[1,14,18],[2,5,7],[6,17,11],[12,13,15]]

编辑:所有子数组的长度相同。并且新数组将具有与旧数组长度相同的子数组。

【问题讨论】:

  • 你的逻辑是什么?
  • 只是随机洗牌?
  • 这只是一个随机的重新排列,但保持相同的尺寸?
  • 我们可以假设所有子数组的长度相同吗?
  • @Barmar - 是的,所有子数组的长度相同,并且需要保持新数组中的子数组与旧数组的长度相同

标签: javascript arrays random shuffle


【解决方案1】:

我会为此使用下划线:http://underscorejs.org/

v = [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18]]
v2 = _.shuffle(_.flatten(v))
v3 = _.groupBy(v2, function(item, i) {
  return i % v.length;
})

【讨论】:

    【解决方案2】:

    这会随机播放,它不会返回新数组:

    function shuffleMatrix (m) {
       if (m.length == 0 || m[0].length == 0) {
           // no rows or columns, just return it
           return m;
       }
       function swap(i1, j1, i2, j2) {
           if (i1 != i2 || j1 != j2) {
               var temp = m[i1][j1];
               m[i1][j1] = m[i2][j2];
               m[i2][j2] = temp;
       }
       var rows = m.length;
       var cols = m[0].length;
       for (i = 0; i < rows; i++) {
           for (j = 0; j < cols; j++) {
               var new_i = Math.random()*rows;
               var new_j = Math.random()*cols;
               swap(i, j, new_i, new_j);
           }
       }
    }
    

    【讨论】:

      【解决方案3】:
      function arrayShuffle(){
        var tmp, rand;
        for(var i =0; i < this.length; i++){
          rand = Math.floor(Math.random() * this.length);
          tmp = this[i]; 
          this[i] = this[rand]; 
          this[rand] =tmp;
        }
      }
      
      Array.prototype.shuffle =arrayShuffle;
      

      然后

      for(var i in arrays){
          arrays[i].shuffle()
      }
      

      与顶层数组中的数组位置相同。

      //编辑:误读:)

      function shuffleAnyNumber (arrays) {
         var numbers = new Array();     //collection of all numbers
      
         for(var i in this){
             for(var j in arrays[i]){
                numbers.push( arrays[i][j]);        //collect numbers out of the given arrays
             }       
         }
      
         numbers.shuffle(); //Method shown above
      
         var output = new Array();
         var tempArray= new Array();
      
         //putting it together
         for(var i in numbers){
             if(tempArray.length == 3){
                  output.push(tempArray);
                  tempArray = new Array();
             } else {
                  tempArray.push(numbers[i]);
             }
         }
      
         return output;
      }
      

      我会说它会这样工作。

      【讨论】:

      • 这看起来它只在每个子数组内洗牌,它不会在子数组之间洗牌。
      • 是的,我有点看错了。但这会起作用,通过将所有数字收集到 1 个数组中,将它们打乱并将它们放回长度为 3 的数组中。
      【解决方案4】:

      您可以将数组展平,shuffle it,然后再次拆分:

      var flat = [].concat.apply([], myArray);
      arrayShuffle(flat);
      var newArray = [],
          sublen = myArray[0].length;
      for (var i=0; i<flat.length; i+= sublen)
          newArray.push(flat.slice(i, i+sublen));
      

      或者您修改现有的随机播放算法之一以使用子数组中的项目。例如,Fisher-Yates-shuffle:

      function shuffle2dArray(array) {
          if (!array.length) return array;
          var sublen = array[0].length,
              len = array.length * sublen;
          for (var i = len - 1; i > 0; i--) {
              var j = Math.floor(Math.random() * (i + 1));
              var ix = ~~(i/sublen),
                  iy = i % sublen,
                  jx = ~~(j/sublen),
                  jy = j % sublen;
              var temp = array[ix][iy];
              array[ix][iy] = array[jx][jy];
              array[jx][jy] = temp;
          }
          return array;
      }
      

      【讨论】:

      • 我喜欢第一个解决方案,因为我已经在我的代码中展平了该数组。
      【解决方案5】:

      我 100% 支持 Ilan Berci 的回答。但是,您可以使用下划线以更实用的方式编写它:

      var v = [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18]];
      
      return _(v).chain().flatten().shuffle().groupBy(function(item, i) { 
          return i % v.length; 
      }).values().value();
      

      下划线!!

      【讨论】:

      • 我完全赞同你的功能重写! :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 2021-05-31
      • 2018-02-18
      • 2016-07-16
      • 2015-12-27
      • 1970-01-01
      相关资源
      最近更新 更多