1

I have a JavaScript array similar to this:

arrTest = [
  {qId: 1, text:"test a", order: 1},
  {qID: 2, text:"test b", order: 2},
  {qID: 3, text:"test c", order: 3},
  {qID: 4, text:"test d", order: 4}
];

I would like to randomize just the order key so that all other keys remain the same and the original order of the array stays as is:

arrTest = [
  {qId: 1, text:"test a", order: 3},
  {qID: 2, text:"test b", order: 1},
  {qID: 3, text:"test c", order: 4},
  {qID: 4, text:"test d", order: 2}
];

I have found lots or randomize array discussions and functions, but can't seem to find one that targets a specific key and leaves everything else the same.

Any assistance is appreciated.

Thank you!

Mark
  • 117
  • 7
  • You're using an array (which is inherently ordered)... why not order the objects using their index and dump the ordering by key? – chazsolo Mar 28 '18 at 17:19

3 Answers3

2

You could map order and take a random value for assignment back to the property.

var arrTest = [{ qId: 1, text:"test a", order: 1 }, { qID: 2, text:"test b", order: 2 }, { qID: 3, text:"test c", order: 3 }, { qID: 4, text:"test d", order: 4 }],
    random = arrTest.map(({ order }) => order);
    
arrTest.forEach(o => o.order = random.splice(Math.floor(Math.random() * random.length), 1)[0]);

console.log(arrTest);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • 1
    Nice trick using splice! I had virtually the same answer but I was stuck on removing the already assigned from the array. As an aside you can use `0| Math.random() * random.length` instead of `Math.floor`, but that definitely doesn't help readability. – zfrisch Mar 28 '18 at 17:34
  • I ended up using something very similar to your code above. I liked the .splice() of the random array to ultimately make the order random. Thanks! – Mark Mar 28 '18 at 22:37
0

Extract the order using Array.map(), shuffle (taken from this answer) the order array, and Array.map() the original array with the new order:

const arrTest = [{"qId":1,"text":"test a","order":1},{"qID":2,"text":"test b","order":2},{"qID":3,"text":"test c","order":3},{"qID":4,"text":"test d","order":4}];

function shuffle(array) {
  for (let i = array.length - 1; i > 0; i--) {
      let j = Math.floor(Math.random() * (i + 1));
      [array[i], array[j]] = [array[j], array[i]];
  }
  
  return array;
}

const result = shuffle(arrTest.map((o) => o.order))
  .map((order, i) => ({
    ...arrTest[i],
    order
  }));
  
console.log(result);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
0

For such task I would make a usage of lodash library (https://lodash.com/docs), it has many nice features, personally I attach this lib to every javascript project Im doing. Here is sample solution:

_(arrTest)
   .map(element => element.order)
   .shuffle()
   .each( (order, index) => arrTest[index].order = order);

console.log(arrTest);
bladekp
  • 1,529
  • 22
  • 29