I am making a matchmaking system where 2 players of the same level will be matched.
My target is how can I remove a duplicate player name in the same array? After removing that duplicate entry, it should be stored on another array(waiting list).
I have provided an example and a screenshot below. Any help will be appreciated. Thank you.
script for matching: (Matching the players with the same level)
const combine = (source) => {
return source.reduce((acc, curr) => {
if (acc[curr.level]) {
const levelArr = acc[curr.level];
const last = levelArr[levelArr.length - 1];
if (last.length === 2) {
levelArr.push([curr])
} else {
last.push(curr)
}
} else {
acc[curr.level] = [
[curr]
];
}
return acc;
}, {})
};
script ajax: (Fetching data from db)
let ajaxResult = []; // the pushed data will be saved here
let save_method;
let table;
let base_url = "<?php echo base_url();?>";
let result = [];
var html = "";
$(document).ready(function() {
//datatables
table = $("#entry_list1").DataTable({
processing: false,
serverSide: true,
order: [],
searching: false,
paging: false,
info: false,
ajax: {
url: "<?php echo site_url('controller/fetch')?>",
type: "POST",
async: true,
dataType: "json",
success: function(data) {
result = combine(data.data2);
console.log(result)
var keys = Object.keys(result)
for (var i = 0; i < keys.length; i++) {
result[keys[i]].forEach(function(val) {
val.forEach(function(value, index) {
var entryIDs = index == 0 ? "entryIDM[]" : "entryIDW[]"
var players = index == 0 ? "playerM[]" : "playerW[]"
var levels = index == 0 ? "levelM[]" : "levelW[]"
html += `<input type="text" name="${entryIDs}" value="${value.entryID}">
<input type="text" name="${players}" value="${value.player}">
<input type="text" name="${levels}" value="${value.level}">
`
})
})
}
document.getElementById("result").innerHTML = html //add html to div
},
},
"columnDefs": [{
"targets": [0], //first column
"orderable": false, //set not orderable
},
{
"targets": [-1], //last column
"orderable": false, //set not orderable
},
],
});
});
I would suggest removing duplicate players before passing them to the combine
function. This way you shouldn't see duplicate players matched.
I would create a removeDuplicates
function to remove duplicate players from the player list.
In this example, we have 18 players, with each player duplicated once.
We run these through the removeDuplicates function, now we have 9 unique players.
We then pass the unique players to the combine
function and get 3 groups of 2 matched players and 3 unmatched players.
const players = Array.from({ length: 18 }, (v,k) => ( { level: Math.floor(k / 6) + 1, player: `test-${Math.floor(k/2)+1}` }));
function removeDuplicates(players) {
return Object.values(players.reduce((acc, curr) => {
acc[curr.player] = acc[curr.player] || curr;
return acc;
}, {}))
}
const combine = (source) => {
return source.reduce((acc, curr) => {
if (acc[curr.level]) {
const levelArr = acc[curr.level];
const last = levelArr[levelArr.length - 1];
if (last.length === 2) {
levelArr.push([curr])
} else {
last.push(curr)
}
} else {
acc[curr.level] = [
[curr]
];
}
return acc;
}, {})
};
console.log("All players:", players);
const uniquePlayers = removeDuplicates(players);
console.log("Unique players:", uniquePlayers);
const matched = Object.values(combine(uniquePlayers)).flatMap(a => a.filter(x => x.length === 2));
const unmatched = Object.values(combine(uniquePlayers)).flatMap(a => a.filter(x => x.length === 1));
console.log("Matched players:", matched);
console.log("Unmatched players:", unmatched);