I am looking to select 2 elements from an array and pair them up. Each element should be selected exactly 4 times and each pair should be unique. For example, if I have the following array:
arr = [p1, p2, p3, p7, p10, p15, p17, p19, p22, p27]
I want to generate something similar to the following:
result: [[p2,p19],[p27,p10],[p15,p3],[p19,p17],[p27,p7],[p3,p17],[p27,p22],[p22,p3],[p15,p1],[p7,p2],[p19,p1],[p17,p15],[p15,p27],[p3,p7],[p10,p22],[p17,p27],[p2,p3],[p27,p1],[p19,p22],[p2,p17]]
In what I have "working" I get unique pairs, however, I do not get exactly 4 instance of each element. I get the following instances for each element: p1 - 3, p2 - 4, p3 - 5, p7 - 3, p10 - 2, p15 - 4, p17 - 5, p19 - 4, p22 - 4, p27 - 6
Here is the array I am using:
let arr = [p1, p2, p3, p7, p10, p15, p17, p19, p22, p27];
Here is the function that I am using:
function selectUniquePairs(arr) {
if (arr.length < 2) {
return "Array must contain at least two elements.";
}
const selectedPairs = new Set();
const result = [];
for (let i = 0; i < arr.length * 2; i++) {
let index1, index2;
do {
index1 = Math.floor(Math.random() * arr.length);
index2 = Math.floor(Math.random() * arr.length);
} while (index1 === index2 || selectedPairs.has(JSON.stringify([index1, index2].sort())));
const pair = [arr[index1], arr[index2]];
result.push(pair);
selectedPairs.add(JSON.stringify([index1, index2].sort()));
}
return result;
}
Any help would be greatly appreciated.
I am wanting to do this in pure javascript, no additional libraries.
The count array is used to keep track of the number of times the arr item occurs in the selectedPairs set.
let arr = ['p1', 'p2', 'p3', 'p7', 'p10', 'p15', 'p17', 'p19', 'p22', 'p27'];
function selectUniquePairs(arr) {
if (arr.length < 2) {
return "Array must contain at least two elements.";
}
const selectedPairs = new Set();
const result = [];
let count=[];//array for keeping track of frequency of each arr element in selectedPairs
for (let i=0;i<arr.length;i++){
count.push(4);//each arr element should occur only 4 times
}
while (!count.every((elt)=>elt==0)){
let index1, index2;
do{
do{
index1 = Math.floor(Math.random() * arr.length);
}while(count[index1]==0);//will find another random element from arr if the element already occurred 4 times in selectedPairs
do{
index2 = Math.floor(Math.random() * arr.length);
}while(count[index2]==0);//will find another random element from arr if the element already occurred 4 times in selectedPairs
}while(selectedPairs.has(JSON.stringify([index1, index2].sort())) || (index1 === index2));
count[index1]--;
count[index2]--; //decrements their frequency each time the element from arr is used within a pair in selectedPairs
const pair = [arr[index1], arr[index2]];
result.push(pair);
selectedPairs.add(JSON.stringify([index1, index2].sort()));
}
return result;
}