Search code examples
javascriptajaxcodeigniter-3

Create another data for single data in array


I'm doing a matchmaking system where 2 players with the same level will be matched (Joined in 1 array). My target is how can I make the player who has no match to have a 2nd data in array?

Example: EntryID: “15”, player: ”testing11”, level: ”3”
         EntryID: ”nm”, player: ”nm”, level: ”nm”;

The example I provided is when a player who doesn't have a match, there should be another data that produces "nm" which means no match.

I have provided an image of my target for better visualization of my problem and target. Thank you so much

enter image description here

Script:

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 = "";




// This is where the same level will be matched
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;
  }, {})
};



// I'm removing the duplicates here. Test 1 vs Test 1 shouldn't be possible
function removeDuplicates(result) {
   return Object.values(result.reduce((acc, curr) => { 
       acc[curr.player] = acc[curr.player] || curr;
       return acc;
   }, {}))
}



const uniquePlayers = removeDuplicates(result);


$(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_players')?>",
            type: "POST",
            async: true,
            dataType: "json",

             success: function(data) {

                 
                result = combine(removeDuplicates(data.data2));
                
            
                
                var keys = Object.keys(result)
                console.log(JSON.stringify(data))
                
                
                
// I am creating a textbox depends on the matches above so that I can insert it on DB. My target here is to produce a textbox for my "no match" player. Because this currently code is only creating textboxes for matched players.
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 

                
               
              
                

            },
        },

        "columnDefs": [{
                "targets": [0], //first column
                "orderable": false, //set not orderable
            },
            {
                "targets": [-1], //last column
                "orderable": false, //set not orderable
            },

        ],
    });
});

json.stringify

{"draw":"1","recordsTotal":5,"recordsFiltered":5,"data":[["15","testing11","3"],["13","testing8","1"],["4","testing4","2"],["3","testing3","2"],["1","testing1","1"]],"data2":[{"entryID":"15","player":"testing11","level":"3"},{"entryID":"13","player":"testing8","level":"1"},{"entryID":"4","player":"testing4","level":"2"},{"entryID":"3","player":"testing3","level":"2"},{"entryID":"1","player":"testing1","level":"1"}]}
  

Solution

  • If your target is only to add input for nm you can check if the JSON Array length is 1 or not . If its 1 it means there is only one match found so you can add other match with nm values inside val.forEach(.. .

    Demo Code:

    //just for demo....
    var data = {
      "data2": [{
        "entryID": "15",
        "player": "testing11",
        "level": "3"
      }, {
        "entryID": "13",
        "player": "testing8",
        "level": "1"
      }, {
        "entryID": "4",
        "player": "testing4",
        "level": "2"
      }, {
        "entryID": "3",
        "player": "testing3",
        "level": "2"
      }, {
        "entryID": "1",
        "player": "testing1",
        "level": "1"
      }, {
        "entryID": "5",
        "player": "testing5",
        "level": "5"
      }]
    }
    
    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;
      }, {})
    };
    
    function removeDuplicates(result) {
      return Object.values(result.reduce((acc, curr) => {
        acc[curr.player] = acc[curr.player] || curr;
        return acc;
      }, {}))
    }
    
    
    result = combine(removeDuplicates(data.data2));
    var keys = Object.keys(result)
    var html = ""
    for (var i = 0; i < keys.length; i++) {
      result[keys[i]].forEach(function(val) {
        var length_ = val.length; //length of the json aray inside obj
        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}">`
    
          //if length is only one
          if (length_ == 1) {
            //just add inputs with nm..
            html += `<input type="text" name="entryIDW[]" value="nm"> <input type="text" name="playerW[]" value="nm"><input type="text" name="levelW[]" value="nm">`
    
          }
    
        })
      })
    }
    document.getElementById("result").innerHTML = html
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="result"></div>