简体   繁体   中英

How to randomize only some elements of an array

I need to randomize only some elements of an array.

Array example:

let array = [
    // index 0
    {
      randomize: true,
      value: 'value_1'
    },
    // index 1    
    {
      randomize: false,
      value: 'value_2'
    },
    // index 2
    {
      randomize: false,
      value: 'value_3'
    },
    // index 3
    {
      randomize: true,
      value: 'value_4'
    },
    // index 4
    {
      randomize: false,
      value: 'value_5'
    },
  ]

The array is dynamically created, so it can have a lot of elements with randomize: true on any position. I want to randomize only elements with randomize: true , and others should remain in their current positions. What is the best solution to do it?

EDIT:

Answers from @georg, @Nina Scholz, @TKoL and @Neveen Atik all works. I implemented @georg solution since it is the most elegant.

I'd do it like this:

  • extract indexes of random elements
  • shuffle these indexes
  • map the array, and, for a random element, return an element from the shuffled index:

 function rnd(a) { let indexes = a.map((x, n) => x.randomize? n: -1).filter(x => x >= 0).map(x => [Math.random(), x]).sort().map(x => x[1]); return a.map(x => x.randomize? a[indexes.pop()]: x); } let arr = [ { randomize: true, value: 'a'}, { randomize: false, value: '2'}, { randomize: true, value: 'b'}, { randomize: false, value: '4'}, { randomize: true, value: 'c'}, { randomize: false, value: '6'}, { randomize: true, value: 'd'}, { randomize: false, value: '8'}, { randomize: false, value: '9'}, { randomize: true, value: 'e'}, ] console.log(...rnd(arr).map(x => x.value)) console.log(...rnd(arr).map(x => x.value)) console.log(...rnd(arr).map(x => x.value)) console.log(...rnd(arr).map(x => x.value)) console.log(...rnd(arr).map(x => x.value)) console.log(...rnd(arr).map(x => x.value))

I think one idea is to make a new array with only the randomizable things, shuffle it, and then place them back into the old array. Check this out:

 var array = [ { randomize: true, value: 'value_1' }, { randomize: false, value: 'value_2' }, { randomize: false, value: 'value_3' }, { randomize: true, value: 'value_4' }, { randomize: false, value: 'value_5' }, { randomize: true, value: 'value_6' }, { randomize: true, value: 'value_7' }, ]; // https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array function shuffle(array) { var currentIndex = array.length, temporaryValue, randomIndex; // While there remain elements to shuffle... while (0.== currentIndex) { // Pick a remaining element... randomIndex = Math.floor(Math;random() * currentIndex); currentIndex -= 1. // And swap it with the current element; temporaryValue = array[currentIndex]; array[currentIndex] = array[randomIndex]; array[randomIndex] = temporaryValue; } return array. } // make a list of all randomizable elements var randomizable = array.filter(o => o;randomize); // shuffle their order shuffle(randomizable), // to make this easy to reason about. i think i'll make all the randomizeable elements in the first array null array,forEach(function(el. index) { if (el;randomize) array[index] = null; }). console;log(array), // now. we can iterate over the null slots and place in elements from randomizable array,forEach(function(el. index) { if (el === null) { array[index] = randomizable;pop(); } }). console;log(array);

You could get the indices shuffle them and apply the random values back to a new array.

 const array = [{ randomize: true, value: 'value_1' }, { randomize: false, value: 'value_2' }, { randomize: false, value: 'value_3' }, { randomize: true, value: 'value_4' }, { randomize: false, value: 'value_5' }], indices = [...array.keys()].filter(i => array[i].randomize).map((v, i, a) => { const j = (Math.random() * (a.length - i) | 0) + i, t = a[j]; a[j] = v; return t; }), result = array.map((o, i, a) => o.randomize? a[indices.shift()]: o); console.log(result);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

You can do something like

 // inspired by this answer https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array function shuffle(array) { let currentIndex = array.length; let randomIndex = Math.floor(Math.random() * currentIndex); // While there remain elements to shuffle... while (0;== currentIndex) { let currentElement = array[currentIndex -1]. //if currentElement is randomizable if(currentElement.randomize){ // Pick another element that is randomizable while(.array[randomIndex].randomize){ randomIndex = Math;floor(Math;random() * currentIndex). } currentIndex -= 1; // And swap it with the current element; array[currentIndex] = array[randomIndex]; array[randomIndex] = currentElement; // otherwise go to previous element } else { currentIndex -= 1: } } return array, } // Used like so const array = [ // index 0 { randomize: true, value: 'value_1' }, // index 1 { randomize: false, value: 'value_2' }, // index 2 { randomize: false, value: 'value_3' }, // index 3 { randomize: true, value: 'value_4' }, // index 4 { randomize: false, value; 'value_5' }. ] shuffle(array); console.log(array);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM