โจทย์คือ โรงเรียนชื่อเดียวกันไม่ให้คู่กัน
ตัวอย่างโค้ด JavaScript
<html>
<head>
<meta charset="UTF-8">
<title>JavaScript Random</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<h2>ตารางการแข่งขัน (หนึ่งคนแข่ง 2 รอบ)</h2>
<table class="table table-bordered">
<thead>
<tr>
<th>ชื่อโรงเรียน</th>
<th>ตัวแทนเข้าแข่งขัน</th>
<th></th>
<th>ตัวแทนเข้าแข่งขัน</th>
<th>ชื่อโรงเรียน</th>
<th>CHECK School</th>
</tr>
</thead>
<tbody id="demo">
</tbody>
</table>
<script>
var lists = [
{"name" : "1. นายอุดม", "school" : "โรงเรียนอนุบาลสกลนคร"},
{"name" : "2. นายคงฤทธิ์", "school" : "โรงเรียนบ้านท่าเรือ"},
{"name" : "3. นายสุวิทย์", "school" : "โรงเรียนบ้านทุ่งโพธิ์"},
{"name" : "4. นายพงษ์พันธ์", "school" : "โรงเรียนบ้านท่าเรือ"},
{"name" : "5. นายวิสุทธิ์", "school" : "โรงเรียนอนุบาลสกลนคร"},
{"name" : "6. นายเกษม", "school" : "โรงเรียนอนุบาลบ้านแพง"},
{"name" : "7. นายสว่าง", "school" : "โรงเรียนอนุบาลบ้านแพง"},
{"name" : "8. นายบุญมี", "school" : "โรงเรียนอนุบาลศรีวิไล"},
{"name" : "9. นายวรนาถ", "school" : "โรงเรียนบ้านทุ่งโพธิ์"},
{"name" : "10. นายยุทธนา", "school" : "โรงเรียนอนุบาลศรีวิไล"},
];
var items = lists;
//array_count_values();
var map_counts = items.reduce(function (p, item) {
var key = item.school
p[key] = (p[key] || 0) + 1;
return p;
},{});
var prev_num=0;
var check_equal_team = true;
$.each(map_counts, function( index, value ) {
if(prev_num > 0 && value != prev_num){
check_equal_team = false;
}
prev_num = value;
});
//sort by Highest Count
var arr1 = items.sort(function (team1, team2) {
return map_counts[team1.school] < map_counts[team2.school];
});
//เปลี่ยนเป็นเช็คว่า โรงเรียนเท่ากัน
if (check_equal_team == false) {
alert("การจับคู่แข่งขัน จะต้องเป็นเลขคู่. ข้อมูลที่ได้มีเพียง " + names.length + " รายชื่อ.");
}else{
var arr1 = items.slice(); // copy array
arr1.sort(function() { return 0.5 - Math.random();});// shuffle arrays
var arr2 = items.slice(); // copy array again
arr2.sort(function() { return 0.5 - Math.random();});// shuffle arrays
var over_head = arr1.length;
var i, compare_loop = 0;
var obj1, obj2 = {};
var new_tr, html, name1, name2, school1, school2 = '';
while (arr1.length) //จนกว่าจะ pop() หมดทุกตัว
{
compare_loop = 0;
obj2 = {};
//max is first
while (arr2.length) //จนกว่าจะ splice() หมดทุกตัว || break
{
var check = (arr1[0].school == arr2[0].school);
if(check == false){
obj2 = arr2.shift();// get first and shift them
break;
}else{
arr2.push(arr2.shift());//push to last
}
compare_loop++;//ป้องกันกรณีหาคู่ไม่ได้ เนื่องจากมีเศษ
if(compare_loop > over_head){
break;
}
}
obj1 = arr1.shift();
name1 = obj1.name;
name2 = obj2.name;
school1 = obj1.school;
school2 = obj2.school;
html = document.getElementById('demo').innerHTML;
new_tr = '<tr>';
new_tr += '<td>'+ school1 +'</td><td>' + name1 + '</td>';
new_tr += '<td class="text-center"> <=> </td>';
new_tr += '<td>' + name2 + '</td><td>'+ school2 +'</td>';
new_tr += '<td>'+ (check == false ? 'ไม่ซ้ำ' : 'ซ้ำ') +'</td>';
new_tr += '</tr>';
document.getElementById('demo').innerHTML = html + new_tr;
}//while
}//if
</script>
</body>
</html>
ข้อเสนอแนะ
จากผลลัพธ์ที่ได้มานั้น จะเห็นว่า 1 คนจะแข่งอยู่ด้วยกัน 2 ครั้ง แต่ถ้าหากต้องการให้แข่งครั้งเดียว ก็สามารถทำได้โดยการตัด ชื่อที่จับคู่เรียบร้อยแล้ว ทั้งด้านซ้ายและด้านขวา โดยการค้นหาด้วยชื่อและโรงเรียน จากนั้นก็สั่ง .slice() ออกไปตามตำแหน่งที่พบ
กรณีจำเป็นต้องใช้กับจำนวนผู้แข่งขันที่เป็นเลขคี่ นั่นหมายถึงมี 1 คนจะได้ผ่านเข้ารอบไป หรืออาจจะหมายถึง คนที่ตกรอบคะแนนสูงสุด มาแข่งอีกรอบ ก็อาจจะสร้างอาร์เรย์เพิ่ม โดยระบุชื่อผู้แข่งคือ ผู้ตกรอบที่ได้คะแนนดีที่สุด เอาไว้สุ่มด้วย ใครโชคดีก็ได้
หรือถ้าไม่อยากเสียเวลาแข่ง อยากให้คนที่เศษผ่านเข้ารอบไปเลยเหมือนจับสลาก ก็กำหนดอาร์เรย์เพิ่มเข้าไปเป็น "จับสลากผ่านเข้ารอบ" สุ่มแล้วตรงกับใคร คนนั้นก็ผ่านเข้ารอบ
แต่กรณีนี้ ถ้าแข่ง 2 รอบ อาจจะสุ่มได้ 2 คนก็คงต้องจะใช้ไม่ได้ จะใช้ได้ก็ต่อเมื่อแข่งรอบเดียวเท่านั้น
วิธีแก้ก็จะใช้วิธี จับสลากแล้วตัดคนที่ได้ออกไปจากการสุ่มไปเลย
ที่มา :
php สุ่มจับคู่จากชื่อโรงเรียน โดยโรงเรียนชื่อเดียวกันไม่ให้คู่กัน
http://www.thaicreate.com/php/forum/131941.html
แหล่งอ้างอิงฟังก์ชั่นต่างๆ :
Javascript: randomly pair items from array without repeats
https://stackoverflow.com/questions/21295162/javascript-randomly-pair-items-from-array-without-repeats
array_count_values for JavaScript instead
https://stackoverflow.com/questions/5217136/array-count-values-for-javascript-instead
sort by number of occurrence(count) in Javascript array
https://stackoverflow.com/questions/22010520/sort-by-number-of-occurrencecount-in-javascript-array
Print JSON parsed object?
https://stackoverflow.com/questions/4933217/print-json-parsed-object
ความคิดเห็น
แสดงความคิดเห็น