Home > Software design >  Appending keys Create another data for single data in array
Appending keys Create another data for single data in array

Time:02-28

My target is to create a key and append them in a DIV. My old function works good but I have made adjustments so I changed my code to a better one. The problem is, I cannot append anymore when the array is = 1.

This is my old code: (We can see here after being matched, they're appended to the DIV using keys. Even if length = 1, there's also a key to append on my div).

//just for demo....
var data = {
  "data2": [{
    "entryID": "1",
    "player": "testing1",
    "level": "3"
  }, {
    "entryID": "2",
    "player": "testing2",
    "level": "1"
  }, {
    "entryID": "3",
    "player": "testing3",
    "level": "2"
  }, {
    "entryID": "4",
    "player": "testing4",
    "level": "2"
  }, {
    "entryID": "5",
    "player": "testing5",
    "level": "1"
  }, {
    "entryID": "6",
    "player": "testing6",
    "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>

This is my new codes and i can't append it when the length is = 1 or 2.

const source = [
  {
    entryID: 1,
    entryName: "player1",
    weight: 1900,
  },
  {
    entryID: 2,
    entryName: "player1",
    weight: 1900,
  },
  {
    entryID: 3,
    entryName: "player3",
    weight: 1905,
  },
  {
    entryID: 4,
    entryName: "player4",
    weight: 1905,
  },
  {
    entryID: 5, 
    entryName: "player5",
    weight: 1910,
  },


];

function combine(
  data = [],
  different = 0,
  maxGroupSize = 2,
  sortedStatement = (a, b) => a.weight - b.weight
) {
  const sortedData = [...data].sort(sortedStatement); 

  const dataGroups = sortedData.reduce((acc, item) => {
    const findedAccItem = acc.find(
      (accItem) =>
        accItem.length < maxGroupSize && 
        accItem[0].weight   different >= item.weight && 
        !accItem.find((obj) => obj.entryName === item.entryName ) 
    );
    if (findedAccItem) {
      findedAccItem.push(item);
    } else {
      acc.push([item]);
    }
    return acc;
  }, []);

  const namedDataGroups = dataGroups.reduce((acc, item, index) => {

    const key = [index, ...item.map((item) => item.weight)].join("_");
    acc[key] = item;
    return acc;
  }, {});

  return namedDataGroups;
}


console.log("Example #1: ", combine(source));

My target is to append the keys. Same as the first snippet. Any help will be appreciated. Thank you so much

CodePudding user response:

You can get the length of the JSON Array outside result[keys[i]] each loop and then using that length you can change your code to append "no match" for length 1 .

Demo Code :

const source = [{
    entryID: 1,
    entryName: "player1",
    weight: 1900,
  },
  {
    entryID: 2,
    entryName: "player2",
    weight: 1900,
  },
  {
    entryID: 3,
    entryName: "player3",
    weight: 1905,
  },
  {
    entryID: 4,
    entryName: "player4",
    weight: 1905,
  },
  {
    entryID: 5,
    entryName: "player5",
    weight: 1910,
  },


];

function combine(
  data = [],
  different = 0,
  maxGroupSize = 2,
  sortedStatement = (a, b) => a.weight - b.weight
) {
  const sortedData = [...data].sort(sortedStatement);
  const dataGroups = sortedData.reduce((acc, item) => {
    const findedAccItem = acc.find(
      (accItem) =>
      accItem.length < maxGroupSize &&
      accItem[0].weight   different >= item.weight &&
      !accItem.find((obj) => obj.entryName === item.entryName)
    );
    if (findedAccItem) {
      findedAccItem.push(item);
    } else {
      acc.push([item]);
    }
    return acc;
  }, []);

  const namedDataGroups = dataGroups.reduce((acc, item, index) => {

    const key = [index, ...item.map((item) => item.weight)].join("_");
    acc[key] = item;
    return acc;
  }, {});

  return namedDataGroups;
}
var result = combine(source);
var keys = Object.keys(result)
var html = ""
for (var i = 0; i < keys.length; i  ) {
  var length_ = result[keys[i]].length; //get length of the json array per keys
  result[keys[i]].forEach(function(value, index) {
    var entryIDs = index == 0 ? "entryIDM[]" : "entryIDW[]";
    var players = index == 0 ? "playerM[]" : "playerW[]";
    var levels = index == 0 ? "levelM[]" : "levelW[]";
    //change to correct key name
    html  = `<input type="text" name="${entryIDs}" value="${value.entryID}"> 
                 <input type="text" name="${players}" value="${value.entryName}">
                 <input type="text" name="${levels}" value="${value.weight}">`
    //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 //append to dom
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="result"></div>

  • Related