如何使用javascript随机生成一对人?

时间:2018-09-03 18:15:03

标签: javascript

我有一个人名单,我想将他们配对,而不必重复他们的名字。

这是我的代码:

var people = ['John', 'Jane', 'Harry', 'Mark', 'Steph', 'Mae']
var generatedPairs = [];
var arr1 = people.slice(),
    arr2 = people.slice();
arr1.sort(function() { return 0.5 - Math.random();});
arr2.sort(function() { return 0.5 - Math.random();});

while (arr1.length) {
  let pair = [];
  var name1 = arr1.pop();
  var name2 = arr2[0] == name1 ? arr2.pop() : arr2.shift();
  pair.push({from: name1, to: name2});
  generatedPairs.push(pair);
}

for(let i in generatedPairs) {
    console.log(generatedPairs[i][0].from+' - '+generatedPairs[i][0].to)
}
console.log("=================");

抽样结果:

Mae - Jane
Jane - Harry
Steph - Mae
John - Steph
Mark - John
Harry - Mark
=================

该代码可以正常工作,因为它的人数是偶数,为6。

但是,如果人数奇数(样本5),则可能会有1个人的名字重复

var people = ['John', 'Jane', 'Harry', 'Mark', 'Steph']
var generatedPairs = [];
var arr1 = people.slice(),
    arr2 = people.slice();
arr1.sort(function() { return 0.5 - Math.random();});
arr2.sort(function() { return 0.5 - Math.random();});

while (arr1.length) {
  let pair = [];
  var name1 = arr1.pop();
  var name2 = arr2[0] == name1 ? arr2.pop() : arr2.shift();
  pair.push({from: name1, to: name2});
  generatedPairs.push(pair);
}

for(let i in generatedPairs) {
    console.log(generatedPairs[i][0].from+' - '+generatedPairs[i][0].to)
}
console.log("=================");

有时结果会是这样。

Steph - Jane
Jane - John
John - Mark
Mark - Steph
Harry - Harry   <-- this one repeat its name
=================

我该如何处理人数众多的情况? 我正在为此使用javascript。希望你能帮助我解决这个问题。谢谢。

这是我的小提琴-> https://jsfiddle.net/g7xsdnbp/9/

2 个答案:

答案 0 :(得分:0)

如果在数组长度大于等于2的情况下循环,则无论数组长度为奇数还是偶数,当我们再没有足够的成对时,它将停止。

我只会使用splice从数组中删除该元素,以避免重复使用元素。除非有令人信服的理由将2个副本存储在内存中,否则我也不会使用2个不同的数组。

我在下面有一个工作示例:

    let people = ['John', 'Jane', 'Harry', 'Mark', 'Steph', 'Mae', 'Justin']
    let set = new Set();

    while (people.length >= 2){
	    let r1 = Math.random() * people.length;
        let person1 = people.splice(r1, 1)[0];
  
        let r2 = Math.random() * people.length;
        let person2 = people.splice(r2, 1)[0];
  
        set.add({from: person1, to: person2});
        console.log("from: " + person1 + " to: " + person2);
    }

希望这会有所帮助!

答案 1 :(得分:0)

以下是可能的解决方案:

  • ((people.length - 1) * people.length)/2给出了可能的不同对(不考虑顺序)和不同名称的数量。 “约翰-简”和“简-约翰”算作一个。

  • 我们可以使用嵌套的for loop获得所有唯一的组合(此处不考虑顺序),但是第二个循环中使用j = i+1可以不重复同一个人。

  • 然后,我们选择一个随机对,并使用随机reverse()决定一对的顺序。然后,我们splice数组不选择同一对。

  • 结果是,我们获得了所有可能的配对组合,顺序是随机的。

let people = ['John', 'Jane', 'Harry', 'Mark', 'Steph']

var pairs = [];

for(let i = 0; i<people.length; i++){
    for(let j = i+1; j<people.length; j++){
    pairs.push([people[i], people[j]])
    }    
}

while(pairs.length){
    let pair = Math.floor(Math.random() * pairs.length)
    let temp = pairs.splice(pair,1);
    if(Math.floor(Math.random()*2)) temp[0].reverse()//<-- pair order
    console.log(temp[0].join(" - "))
}