Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript - split array into groups with random number of objects

I am working on this little app and I have an array of more than 100 objects which I want to split in groups. The tricky part is that I want my newly created arrays to contain random number of objects. For example:

initial: ["a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13", "a14", "a15", "a16", "a17", "a18", "a19"]

modified: ["a0", "a1", "a2"], ["a3", "a4", "a5", "a6", "a7"], ["a8"], ["a9", "a10"]...

I think you get the idea. I was stuck with this for the last few hours and I just can't figure it out.

I hope you can help me! Thanks a lot

like image 550
betmenas Avatar asked Dec 15 '25 01:12

betmenas


1 Answers

Since you didn't specify minimum number of arrays or min/max elements per array, here's a general purpose function that you can specify min/max elements for each array. Note though that this doesn't strictly enforce min elements, and indeed it may be impossible to 100% do, depending on how many elements there are in the original array vs. how many are randomly assigned to each array element. For example if you have 10 elements original and you do min 2 max 4, you could end up with 3/3/3/1, because the min will be enforced up until there's not enough to enforce. You didn't really give any "rules" about that.

min and max are both optional and default to 1. If only min is specified, max will default to min.

also note that since arrays are passed by reference, this will by default "empty" the original array. If you want to preserve the original array, uncomment the first line in the function (obviously n/a if you opt to prototype it).

function randChunkSplit(arr,min,max) {
  // uncomment this line if you don't want the original array to be affected
  // var arr = arr.slice();
  var arrs = [],size=1; 
  var min=min||1;
  var max=max||min||1;
  while (arr.length > 0) {
    size = Math.min(max,Math.floor((Math.random()*max)+min));
    arrs.push(arr.splice(0, size));
  }
  return arrs;
}

examples

var letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];

// randChunkSplit(letters)
[["a"], ["b"], ["c"], ["d"], ["e"], ["f"], ["g"], ["h"], ["i"], ["j"], ["k"], ["l"], ["m"], ["n"], ["o"], ["p"], ["q"], ["r"], ["s"], ["t"], ["u"], ["v"], ["w"], ["x"], ["y"], ["z"]]

// randChunkSplit(letters,3)
[["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"], ["j", "k", "l"], ["m", "n", "o"], ["p", "q", "r"], ["s", "t", "u"], ["v", "w", "x"], ["y", "z"]]

// randChunkSplit(letters,1,3)
[["a"], ["b", "c"], ["d", "e"], ["f", "g", "h"], ["i", "j", "k"], ["l"], ["m"], ["n", "o"], ["p", "q"], ["r"], ["s", "t"], ["u", "v", "w"], ["x", "y", "z"]]

// randChunkSplit(letters,2,3) 
[["a", "b", "c"], ["d", "e", "f"], ["g", "h"], ["i", "j", "k"], ["l", "m", "n"], ["o", "p", "q"], ["r", "s", "t"], ["u", "v", "w"], ["x", "y", "z"]]

// randChunkSplit(letters,2,3)
// same thing as before, but notice how this time we end up with just 1 elem left over
[["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"], ["j", "k", "l"], ["m", "n", "o"], ["p", "q"], ["r", "s"], ["t", "u", "v"], ["w", "x", "y"], ["z"]]

Alternatively, you could prototype it to Array if you want, something like this:

Array.prototype.randChunkSplit = function (min,max) {
  var arrs = [],size=1; 
  var min=min||1;
  var max=max||min||1;
  while (this.length > 0) {
    size = Math.min(max,Math.floor((Math.random()*max)+min));
    arrs.push(this.splice(0, size));
  }
  return arrs;
}

var letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];

letters.randChunkSplit(1,4)
like image 106
Crayon Violent Avatar answered Dec 16 '25 23:12

Crayon Violent



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!