1

I have an array of numbers from 1 to 60

var originalArray = [1, 2, 3, 4 .... 58, 59, 60] // etc

I want to - depending on another number between 2 and 4 - split those numbers randomly into the number of arrays specified, and for the result to be unique each and every time.

For example:

distributeArray(2) should result in two arrays, each with 30 numbers randomly selected from the original array.

distributeArray(3) should result in three arrays, each with 20 numbers randomly selected from original array.

I assume this is a reasonably common case so any pointers would be appreciated. Thanks in advance.

Paulos3000
  • 3,355
  • 10
  • 35
  • 68
  • 3
    Shuffle the array and split it into `n` parts? Both have been asked before: [How to randomize (shuffle) a JavaScript array?](http://stackoverflow.com/q/2450954/218196), [Split array into chunks](http://stackoverflow.com/q/8495687/218196) – Felix Kling Dec 28 '16 at 00:27
  • @FelixKling - thanks, hadn't thought of that! I found this other answer useful for how to do that, if anyone else is interested: http://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array-in-javascript – Paulos3000 Dec 28 '16 at 00:31

2 Answers2

0

You could do something like this, first shuffle and then split array into n parts.

var arr = [...Array(61).keys()].slice(1)

function splitRandom(data, n) {
  var seen = [];
  var counter = 0;

  var shuffle = data.reduce(function(r, e) {
    function random() {
      var rand = parseInt(Math.random(0, arr.length) * arr.length);
      if (seen.indexOf(rand) != -1) {
        return random()
      } else {
        seen.push(rand)
        return rand;
      }
    }

    r[random()] = e;
    return r;
  }, [])

  var split = shuffle.reduce(function(r, e) {
    var c = counter++;
    r[c] = r[c].concat(e)
    counter = counter % n;
    return r;
  }, Array(n).fill([]))

  return split;
}

console.log(JSON.stringify(splitRandom(arr, 3)))
console.log(JSON.stringify(splitRandom(arr, 10)))
console.log(JSON.stringify(splitRandom(arr, 50)))
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
0

You can create a function which creates an array of n .length, and an array of x .length. Use do..while loop Array.prototype.splice() to remove a random index from originalArray, .push() the element to one of x random arrays, until originalArray.length evaluates to false, return array of arrays containing values.

const randomArrays = (n, x) => {
  
  let [originalArray, result, len] = [
    Array.from({length: n}, (_, key) => key)
  , Array.from({length: x}, () => [])
  , Math.ceil(n / x)
  ];
  do {
    let [curr, index] = [
      originalArray
      .splice(Math.floor(Math.random() * originalArray.length), 1)
      .pop()
      , Math.floor(Math.random() * result.length)
    ];
    if (result[index].length < len)
      result[index].push(curr);
    else
      for (let i = 0; i < result.length; i++) {
        if (result[i].length < len) {
          result[i].push(curr);
          break;
        }
      }
  } while (originalArray.length);
  
  return result
  
}

console.log(
  randomArrays(60, 3)
  , randomArrays(21, 7)
  , randomArrays(5, 3)
  , randomArrays(27, 5)
);
guest271314
  • 1
  • 15
  • 104
  • 177