简体   繁体   English

如何仅随机化数组的某些元素

[英]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.该数组是动态创建的,因此它可以有很多randomize: true I want to randomize only elements with randomize: true , and others should remain in their current positions.我只想用randomize: true随机化元素,其他元素应该保持在当前位置。 What is the best solution to do it?最好的解决方案是什么?

EDIT:编辑:

Answers from @georg, @Nina Scholz, @TKoL and @Neveen Atik all works. @georg、@Nina Scholz、@TKoL 和 @Neveen Atik 的回答都有效。 I implemented @georg solution since it is the most elegant.我实现了@georg 解决方案,因为它是最优雅的。

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: map 数组,对于随机元素,从洗牌索引中返回一个元素:

 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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