我需要以下方面的帮助,这是一些 json 数据
[
{
"id" : 1,
"from" : 10,
"to" : 11
},
{
"id" : 2,
"from" : 11,
"to" : 12
},
{
"id" : 3,
"from" : 10.5,
"to" : 11.5
},
{
"id" : 4,
"from" : 9,
"to" : 9.5
}
]
我正在尝试像这样准备数据,我可以在屏幕上显示它,因此每个对象将包含 2 个附加属性,sum 和 col(列)。Sum 是组成组的列(每说)的总和,col 是对象所在的列。这是示例数据。因此,我正在寻找一种递归的方式来遍历数据以设置这两个附加属性。数据现在应如下所示:
[
{
"id" : 1,
"from" : 10,
"to" : 11,
"sum" : 2,
"col" : 1
},
{
"id" : 2,
"from" : 11,
"to" : 12,
"sum" : 2,
"col" : 1
},
{
"id" : 3,
"from" : 10.5,
"to" : 11.5,
"sum" : 2,
"col" : 2
},
{
"id" : 4,
"from" : 9,
"to" : 9.5,
"sum" : 1,
"col" : 1
}
]
因此,由于项目 id:3 from 介于 id:1 和 id:2 from 和 to 之间,请注意这三个项目的 sum 属性为 2,并且 id:3 的列为 2。我想这是数据的简单版本。可能存在额外的嵌套,例如,额外的对象总和可能等于 3,col 等于 3。
我不确定这类似于什么数据结构?某种树。如何遍历这些项目(思考递归)并以最小的时间复杂度设置这些附加属性?也许我先排序了。
任何方向或帮助将不胜感激!
您需要为每个数组元素分配两个属性。pos
是列表窗体中的计划列。当有两个或多个重叠约会时,位置 1 用于第一个约会,位置 2 用于第二个约会,依此类推。
pos = 1 pos = 2
--------------------------- -------------------------------
{ id: 1, from: 10, to: 11 } { id: 3, from: 10.5, to: 11.5 }
{ id: 2, from: 11, to: 12 }
{ id: 4, from: 12, to: 13 }
sum
,我想我已经理解了,同时约会的数量。
对于第一部分,解决方案使用帮助程序变量 schedule
。此变量模拟包含约会的表。在每个数组中,所有约会都是不重叠的。数组大小对应于所需的pos
。
第二部分计算sum
,甚至可能同时进行多少次约会的指标。在这里,使用最大计数。
该算法需要排序的数据。
结果中的第一个数组是计划。第二个是原始数组,排序并附加了所需的属性 pos
和 sum
。
var data = [
{ id: 1, from: 10, to: 11 },
{ id: 3, from: 10.5, to: 11.5 },
{ id: 2, from: 11, to: 12 },
{ id: 4, from: 12, to: 13 },
],
schedule = [];
data.sort(function (a, b) { return a.from - b.from || a.to - b.to; });
data.forEach(function (a, i) {
schedule.some(function (b, j) {
if (b.length && b[b.length - 1].to <= a.from) {
b.push(a);
return true;
}
}) || schedule.push([a]);
});
schedule.forEach(function (a, i) {
a.forEach(function (b) {
b.pos = i + 1;
});
})
data.forEach(function (a, i, aa) {
var j, sum = 1;
while (i + sum < data.length && data[i + sum].from < a.to && a.to <= data[i + sum].to) {
sum++;
}
for (j = i; j < i + sum; j++) {
if (!(aa[j].sum >= sum)) {
aa[j].sum = sum;
}
}
});
document.write('<pre>' + JSON.stringify(schedule, 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>');