我按照以下要求获取以下代码的输出:
当我使用DOM将结果输出到页面时。如果数组元素的数量不能被部分变量的数目均匀地整除,则将所有余数放入最后部分,如下所示。我无法正确完成这整个任务。
(注意:当提到创建“节”时,我并不是指div。下面的期望输出应该使事情更清楚。)
示例数组输入 [4,4,4,4,2,4,4,4,4,4,2,2,2,3,2,2,2,2,2,3,3,3,7,3,3,3 ,1,6,6,1,1,1,1,1,7,7,7,7,6,6]
当前示例输出:4-9倍,2-8倍,3-7倍,1-6 次,7-5次,6-4次
所需的输出:示例1(sections变量= 3):
4-9次
2-8次3-7次
1-6次7-5次
6-4次所需的输出:示例2(sections变量= 2):
4-9次
2-8次
3-7次1-6次
7-5次
6-4次所需的输出:示例3(sections变量= 4):
4-9次
2-8次
3-7次
1-6次
7-5次
6-4次
到目前为止,我的代码:
Controller_OnPlayerChangedState
private void Controller_OnPlayerChangedState(object sender, MultiPlayerController.OnChangeStateEventArgs e)
{
if (e.NewState == AudioPlayer_State.Playing)
{
Duration = AudioPanel.Controller.GetDuration();
panel.SetCurrentPositionAsync((long)Duration);
}
else if(e.NewState != AudioPlayer_State.Playing && e.NewState != AudioPlayer_State.Paused)
panel.SetCurrentPositionAsync(0);
}
答案 0 :(得分:3)
您可以使用模运算符%
检查数组元素的数目是否可被段数均匀除。
以下是有效的实现。在这里,我将节的数量设置为全局变量,并使用<br>
(HTML中的换行元素)分隔节。
编辑:将分组计算和格式化分为两个不同的功能。修改后的实现,以便将最大数量的元素放入前nGroups-1
节中(而不是仅将一个元素放入前nGroups-1
节中)。
const duplicateArr2 = [4,4,4,4,2,4,4,4,4,4,2,2,2,3,2,2,2,2,3,3,3,7,3,3,3,1,6,6,1,1,1,1,1,7,7,7,7,6,6,55,55,67,67,45,54,45,54,100,100,200,200,300,300];
const getArrayOfDuplicated = array => {
const hash = array.reduce((a, c) => (a[c] = ++a[c] || 1, a), {});
return Object.entries(hash)
.filter(([k, v]) => v > 1)
.sort(([ak, av], [bk, bv]) => bv - av)
.reduce((a, [k, v]) => [...a, `${k} - ${v} times`], [])
};
// given a number of items to be sectioned into a certain number of groups
// returns a list of length nGroups with the number of items in each group
// such that at least (nGroups - 1) groups contain an equal number of items
// eg. getGrouping(10, 2) -> [5, 5]
// eg. getGrouping(10, 6) -> [1, 1, 1, 1, 1, 5]
const getGrouping = (nItems,nGroups) => {
if (nGroups > nItems)
return Array(nItems).fill(1);
else if (!(nItems % nGroups))
return Array(nGroups).fill(parseInt(nItems / nGroups));
else {
let numberOfEqualGroups = nGroups-1;
var itemsPerEqualGroup;
if (!(nItems % (nGroups-1)))
itemsPerEqualGroup = parseInt(nItems / (nGroups - 1)) - 1;
else
itemsPerEqualGroup = parseInt(nItems / (nGroups - 1));
equalGroups = Array(numberOfEqualGroups).fill(parseInt(itemsPerEqualGroup));
remainder = nItems - itemsPerEqualGroup * numberOfEqualGroups;
return equalGroups.concat(remainder);
}
}
// takes an array and formats it into sections according to grouping
// returns a string with a newline after each line and two new lines between sections
const formatGrouping = (array,grouping) => {
var outputString = ""
var linesDone = 0;
for (var section = 0; section < grouping.length; section++) {
for (var line = 0; line < grouping[section]; line++) {
outputString += array[linesDone] + '<br>';
linesDone += 1;
}
outputString += '<br>';
}
return outputString;
};
var numberOfSections = 3;
result = getArrayOfDuplicated(duplicateArr2);
document.getElementById("jsresultsoutput").innerHTML = formatGrouping(result,getGrouping(result.length,numberOfSections));
<p id="jsresultsoutput"></p>
答案 1 :(得分:1)
我将其分为两个函数,其中一个将您的值分组为值和出现对象的数组。另一个函数将数组和节数作为参数,并正确分配对象。
const input = [4,4,4,4,2,4,4,4,4,4,2,2,2,3,2,2,2,2,3,3,3,7,3,3,3,1,6,6,1,1,1,1,1,7,7,7,7,6,6];
const getOccurrences = (input) => {
return input
.reduce((acc, current) => {
const occurrence = acc.find(el => el.value === current);
if (occurrence) {
occurrence.repeats += 1;
return acc;
}
return [...acc, {
value: current,
repeats: 1
}];
}, [])
.sort((a, b) => b.repeats - a.repeats);
}
const intoSections = (occurrences, sections) => {
const mappedSections = {};
if (occurrences.length % sections === 0) {
let lastIndex = 0;
for (let i = 1; i <= sections; i++) {
mappedSections[`section_${i}`] = occurrences.slice(lastIndex, lastIndex + occurrences.length / sections);
lastIndex += occurrences.length / sections;
}
} else {
for (let i = 1; i <= sections; i++) {
const members = i === sections ? occurrences.slice(sections - 1) : occurrences.slice(i - 1, i);
if (members.length > 0) {
mappedSections[`section_${i}`] = members;
}
}
}
return mappedSections;
}
const toString = (mappedSections) => {
let result = '';
for (const [sectionId, sectionMembers] of Object.entries(mappedSections)) {
const members = sectionMembers.map(el => `${el.value} - ${el.repeats} times`).join('\n');
result += `${sectionId}:\n${members}\n`;
}
return result;
}
const sections = 8;
const occurrences = getOccurrences(input);
console.log(occurrences);
console.log(toString(intoSections(occurrences, sections)));
答案 2 :(得分:1)
尝试一下
const duplicateArr2 = [4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 2, 2, 2, 3, 2, 2, 2, 2, 3, 3, 3, 7, 3, 3, 3, 1, 6, 6, 1, 1, 1, 1, 1, 7, 7, 7, 7, 6, 6];
const getStringOfDuplicated = array => {
const hash = array.reduce((a, c) => (a[c] = ++a[c] || 1, a), {});
return Object.entries(hash)
.filter(([k, v]) => v > 1)
.sort(([ak, av], [bk, bv]) => bv - av)
.reduce((a, [k, v]) => [...a, `${k} - ${v} times`], [])
.join(', ');
};
// the output of your function was an object so I had convert it into an array
var arr = getStringOfDuplicated(duplicateArr2).toString().split(',');
arr = arr.map(function(e){return e.trim();}); // trimmed whitespaces for each element
sections = 5; // number of sections
var length = arr.length;
if(sections > length)
sections = length;
var no_of_elems = 0;
var results = [];
if (length % sections == 0) {
no_of_elems = length / sections;
for (let i = 0; i < length; i+=no_of_elems) {
results.push(arr.slice(i, i + no_of_elems))
}
} else {
no_of_elems = length / sections;
remainder = length % sections;
for (let i = 0; i < sections - 1; i++) {
results.push(arr.slice(i, i + no_of_elems));
}
results.push(arr.slice(sections - 1, sections + remainder));
}
console.log(results); // desired result