Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
448 views
in Technique[技术] by (71.8m points)

javascript - 如何有效地随机选择数组项而不重复?(How to efficiently randomly select array item without repeats?)

I'm aware that this question is around in many guises but I have not been able to find an answer relating to my specific issue of efficiency.

(我知道这个问题有很多种,但是我还没有找到与我的效率问题相关的答案。)

I have the below code that works just fine.

(我有下面的代码可以正常工作。)

I have a 10 item array from which I randomly select an item (on enter key press).

(我有一个10个项目的数组,可以从中随机选择一个项目(按Enter键)。)

The code keeps an array of the 5 most recent choices which cannot be randomly selected (to avoid too much repetition over time).

(该代码包含不能随机选择的5个最近选择的数组(以避免随着时间的推移而重复过多)。)

If the chooseName() function initially selects a name that has been used in the recent 5 goes it simply breaks and calls itself again, repeating until it finds a "unique" name.

(如果ChooseName()函数最初选择了最近5次使用的名称,它只会中断并再次调用自身,重复进行直到找到“唯一”名称。)

I have two questions:

(我有两个问题:)

  1. Is it correct to say this is a "recursive function"?

    (说这是“递归函数”是否正确?)

  2. I am worried that theoretically this could keep looping for a long time before finding a unique name - is there a more efficient way to do this?

    (我担心从理论上讲,这可能会持续很长时间才能找到唯一的名称-是否有更有效的方法?)

Thank you for any help.

(感谢您的任何帮助。)

    var a = ["Roger", "Russell", "Clyde", "Egbert", "Clare", "Bobbie", "Simon", "Elizabeth", "Ted", "Caroline"];
    var b = [];

    var chooseName = function () {
    var unique = true;
    b.length = 5;
    num = Math.floor(Math.random() * a.length);
    name = a[num];    
        for (i = 0; i < a.length; i++) {
        if (b[i] == name) {
            chooseName();
            unique = false;
            break;
            }
        }
        if (unique == true) {
        alert(name);
        b.unshift(name);
        }
    }


    window.addEventListener("keypress", function (e) {
        var keycode = e.keyCode;
        if (keycode == 13) {
        chooseName();
        }
    }, false);
  ask by Russell translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I like commenter @YuriyGalanter's idea of choosing items randomly until all are taken and only then repeating, so here's an implementation:

(我喜欢评论者@YuriyGalanter的想法,即随机选择所有项目,直到所有项目都被提取,然后再重复,所以这里是一个实现:)

function randomNoRepeats(array) {
  var copy = array.slice(0);
  return function() {
    if (copy.length < 1) { copy = array.slice(0); }
    var index = Math.floor(Math.random() * copy.length);
    var item = copy[index];
    copy.splice(index, 1);
    return item;
  };
}

var chooser = randomNoRepeats(['Foo', 'Bar', 'Gah']);
chooser(); // => "Bar"
chooser(); // => "Foo"
chooser(); // => "Gah"
chooser(); // => "Foo" -- only repeats once all items are exhausted.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...