my target is to combine 2 arrays in 1 array if they have the same level.
For example i have testing 1 = level 1 and testing 4 = level 1. They'll be joined in 1 array because they have the same level.
The below script I provided is what combines 2 arrays in 1 if they have the same level. How can I achieve the target that I stated above? Thank you, guys. I provided my codes and images below.
[An Image of what I'm fetching] [An Image of my target when 2 scripts are joined]
Ajax:
var ajaxResult=[]; // the pushed data will be saved here
var save_method;
var table;
var base_url = '<?php echo base_url();?>';
$(document).ready(function() {
//datatables
table = $('#entry_list').DataTable({
dom: 'lBfrtip',
buttons: [
'print', 'csv', 'copy', 'excel', 'pdfHtml5'
],
"processing": false,
"serverSide": true,
"order": [],
"ajax": {
"url": "<?php echo site_url('controller/fetch_players')?>",
"type": "POST",
async:true,
dataType: "json",
success: function(data){
ajaxResult.push(data); // I'm pushing my data to my ajaxResult variable
console.log(ajaxResult);
},
},
"columnDefs": [
{
"targets": [ 0 ],
"orderable": false,
},
{
"targets": [ -1 ],
"orderable": false,
},
],
});
});
script:
//script for combiningng data in 1 array if they have the same level.
const ajaxResult= [] // I'm calling here what I fetched on my ajax.
const matching = (list, keyGetter) => {
let mapping = {};
const map = new Map();
list.forEach((item) => {
const key = keyGetter(item);
const collection = map.get(key);
if (!collection) {
map.set(key, [item]);
} else {
collection.push(item);
}
});
Array.from(map).map(([key, value]) => Object.assign(mapping, { [key]: value }));
return mapping
}
const result = matching(ajaxResult, ({ level}) => { return level});
console.log("RESULT", result); // when i do console.log, the result me be testing 1 and testing 4 in 1 array, so is testing 2 and testing 4
You can use array.reduce
to achieve the desired behaviour.
const source = [
{id: 1, name: 'player1', level: 1},
{id: 2, name: 'player2', level: 2},
{id: 3, name: 'player3', level: 3},
{id: 4, name: 'player4', level: 1},
{id: 5, name: 'player5', level: 2},
{id: 6, name: 'player6', level: 3},
]
const combine = (source) => {
return source.reduce((acc,curr) => {
if(acc[curr.level])
acc[curr.level].push(curr);
else
acc[curr.level] = [curr];
return acc;
},{})
}
console.log('Result', combine(source));
Explanation:
A reducer iterates through and array and for each iteration, it can hold the result of the previous computation. Using this idea, we first check if we have an array for the level computed, if yes, we just push the current object into the array. If not, we create a new array with the current object as the first element.
P.S: I'd recommend adding logs to check values of acc
and curr
on each iteration to understand this better.
Edit: Showcasing how to use with Ajax response:
let ajaxResult = []; // the pushed data will be saved here
let save_method;
let table;
let base_url = "<?php echo base_url();?>";
let result = [];
const combine = (source) => {
return source.reduce((acc, curr) => {
if (acc[curr.level])
acc[curr.level].push(curr);
else
acc[curr.level] = [curr];
return acc;
}, {})
}
$(document).ready(function() {
//datatables
table = $("#entry_list").DataTable({
dom: "lBfrtip",
buttons: ["print", "csv", "copy", "excel", "pdfHtml5"],
processing: false,
serverSide: true,
order: [],
ajax: {
url: "<?php echo site_url('controller/fetch_players')?>",
type: "POST",
async: true,
dataType: "json",
success: function(data) {
ajaxResult.push(data); // I'm pushing my data to my ajaxResult variable
result = combine(ajaxResult); // Cleanup your data here.
},
},
columnDefs: [{
targets: [0],
orderable: false,
},
{
targets: [-1],
orderable: false,
},
],
});
});