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>