我有一个数组,其中包含一些相邻矩形的组:
var paths = [
[3,4,6,7],
[8,10],
[13]
];
矩形定义如下:
var rectangles = [
{id:1,left:[],right:[2]},
{id:2,left:[1],right:[11]},
{id:3,left:[2],right:[4]},
{id:4,left:[3],right:[5]},
{id:5,left:[11],right:[6,12]},
{id:6,left:[5],right:[7]},
{id:7,left:[6],right:[]},
{id:8,left:[],right:[9]},
{id:9,left:[8],right:[10]},
{id:10,left:[9],right:[2]},
{id:11,left:[2],right:[5]},
{id:12,left:[5],right:[]},
{id:13,left:[],right:[9]}
];
从矩形定义中,我看到矩形4和6不是邻居,因为4不是6的右边,6不是4的左边。8和10相同。
现在,我想将路径数组拆分为每组相邻矩形的单独条目,如下所示:
result = [
[3,4],
[6,7],
[8],
[10],
[13]
];
当我找到两个不相邻矩形的两个连续id时,我如何拆分数组并创建新条目?
摆弄测试数据:https://jsfiddle.net/4jpy84k4/
修改 感谢Tobias K的最终解决方案:https://jsfiddle.net/j1of5p4c/4/
答案 0 :(得分:1)
没有转换你的反应,这是我的解决方案:
var paths = [
[3,4,6,7],
[8,10],
[13]
];
var rectangles = [
{id:1,left:[],right:[2]},
{id:2,left:[1],right:[11]},
{id:3,left:[2],right:[4]},
{id:4,left:[3],right:[5]},
{id:5,left:[11],right:[6,12]},
{id:6,left:[5],right:[7]},
{id:7,left:[6],right:[]},
{id:8,left:[],right:[9]},
{id:9,left:[8],right:[10]},
{id:10,left:[9],right:[2]},
{id:11,left:[2],right:[5]},
{id:12,left:[5],right:[]},
{id:13,left:[],right:[9]}
];
function getRectangle(index){
for (var i=0; i<rectangles.length; i++){
if (rectangles[i].id == index){
return rectangles[i];
}
}
return undefined;
}
function isNeighbour(p1, p2) {
var r1 = getRectangle(p1);
var r2 = getRectangle(p2);
if (r1 == undefined || r2 == undefined){
return false;
}
return r1.left.indexOf(p2) >= 0 || r1.right.indexOf(p2) >= 0 || r2.left.indexOf(p1) >= 0 || r2.right.indexOf(p1) >= 0;
}
function groupPaths(paths) {
var results = [];
var neighb = [];
for (var i=0; i<paths.length; i++){
if (paths[i].length == 1){
results.push(paths[i]);
continue;
}
for (var j=0; j<paths[i].length; j++){
if (j+1 == paths[i].length){
neighb.push(paths[i][j]);
results.push(neighb);
neighb = [];
continue;
}
while(isNeighbour(paths[i][j], paths[i][j+1])){
neighb.push(paths[i][j]);
j = j+1;
}
neighb.push(paths[i][j]);
results.push(neighb);
neighb = [];
}
}
return results;
}
var res = groupPaths(paths);
for (var i=0; i<res.length; i++){
for(var j=0; j<res[i].length; j++){
console.log(i + ': ' + res[i][j]);
}
}
&#13;
答案 1 :(得分:0)
这是你可能会这样做的。但首先,为了提高效率,我必须将您的rectangles
参考数据转换为更加可用的形式。 rectangleIds
查找对象看起来像这样;
{ '1': { left: 0, right: 2 },
'2': { left: 1, right: 11 },
'3': { left: 2, right: 4 },
'4': { left: 3, right: 5 },
'5': { left: 11, right: 6 },
'6': { left: 5, right: 7 },
'7': { left: 6, right: 0 },
'8': { left: 0, right: 9 },
'9': { left: 8, right: 10 },
'10': { left: 9, right: 2 },
'11': { left: 2, right: 5 },
'12': { left: 5, right: 0 },
'13': { left: 0, right: 9 } }
然后它只是两个嵌套缩减的问题。
var paths = [
[3,4,6,7],
[8,10],
[13]
],
rectangles = [
{id:1,left:[],right:[2]},
{id:2,left:[1],right:[11]},
{id:3,left:[2],right:[4]},
{id:4,left:[3],right:[5]},
{id:5,left:[11],right:[6,12]},
{id:6,left:[5],right:[7]},
{id:7,left:[6],right:[]},
{id:8,left:[],right:[9]},
{id:9,left:[8],right:[10]},
{id:10,left:[9],right:[2]},
{id:11,left:[2],right:[5]},
{id:12,left:[5],right:[]},
{id:13,left:[],right:[9]}
],
rectangleIds = rectangles.reduce((o,r) => (o[r.id] = {left: r.left[0] || 0, right: r.right[0] || 0},o),{}),
orderedPaths = paths.reduce((sol,p) => sol.concat(p.reduce((res,c,i,a) => rectangleIds[c].left === a[i-1] ||
rectangleIds[c].right === a[i-1] ? (res[res.length-1].push(c),res)
: res.concat([[c]])
,[]))
,[]);
console.log(orderedPaths);
&#13;
答案 2 :(得分:0)
您可以使用Map
和Array#forEach
作为内部循环的paths
和Array#reduce
的外部循环,并使最后一个节点可用于内部的比较部分用于分配给新数组或仅附加到最后一个结果数组的回调函数。
var paths = [[3, 4, 6, 7], [8, 10], [13]],
rectangles = [{ id: 1, left: [], right: [2] }, { id: 2, left: [1], right: [11] }, { id: 3, left: [2], right: [4] }, { id: 4, left: [3], right: [5] }, { id: 5, left: [11], right: [6, 12] }, { id: 6, left: [5], right: [7] }, { id: 7, left: [6], right: [] }, { id: 8, left: [], right: [9] }, { id: 9, left: [8], right: [10] }, { id: 10, left: [9], right: [2] }, { id: 11, left: [2], right: [5] }, { id: 12, left: [5], right: [] }, { id: 13, left: [], right: [9] }],
rectanglesMap = new Map,
result = [];
rectangles.forEach(function (a) {
rectanglesMap.set(a.id, a);
});
paths.forEach(function (a) {
a.reduce(function (r, b, i) {
if (!i || r !== rectanglesMap.get(b).left[0]) {
result.push([b]);
} else {
result[result.length - 1].push(b);
}
return b;
}, undefined);
});
console.log(result);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;