使用JavaScript,我想基于重合的点将一个大的坐标数组拆分成更小的数组。我不是100%确定如何在代码中编写以下内容,但它描述了我正在尝试实现的目标:
遍历数组
var A = [(1,2)(1,3)(2,3)(9,10)(9,11)(10,11)];
合并包含任何匹配/相同坐标点的对:
var B = (1,2)(1,3)(2,3)
var C = (9,10)(9,11)(10,11)
合并匹配/相同点,并从第2点的组合中创建新的较小数组
var D = [1,2,3]
var E = [9,10,11]
我可以得到帮助吗?
答案 0 :(得分:1)
工作回答:http://jsfiddle.net/y3h9L/
好的,所以如果我理解要求A是一维数组,假设在x,y对中有偶数个元素。
A = [1,2, 1,3, 2,3, 9,10, 9,11, 10,11]
// output should be
[ [1,2,3], [9,10,11] ]
// but if you add an extra pair that links the two halves, say add 2,11
A2 = [1,2, 1,3, 2,3, 9,10, 9,11, 10,11, 2,11]
// then all are related so output should be
[ [1,2,3,9,10,11] ]
我没有努力改进或优化以下代码,但它确实有效:
// single dimensional array of x,y pairs
var A = [1,2, 1,3, 2,3, 9,10, 9,11, 10,11];
// create a working copy of A so that we can remove elements
// and still keep the original A intact.
var workingCopy = A.slice(0, A.length),
matchedPairs = [],
currentMatches,
finalCombinations = [],
x, y, i, j,
tempArray;
while (workingCopy.length > 0) {
currentMatches = [];
currentMatches.push([workingCopy.shift(),workingCopy.shift()]);
workingCopyLoop:
for (x=0,y=1; x < workingCopy.length;) {
for (i=0; i < currentMatches.length; i++){
if (workingCopy[x] === currentMatches[i][0]
|| workingCopy[y] === currentMatches[i][1]) {
currentMatches.push([workingCopy.shift(),workingCopy.shift()]);
// go back to the beginning of workingCopyLoop
x=0;
y=1;
continue workingCopyLoop;
}
}
x += 2;
y += 2;
}
matchedPairs.push(currentMatches);
}
for (i=0; i<matchedPairs.length; i++){
tempArray = [];
for (j=0; j<matchedPairs[i].length; j++) {
// I assume you have a new enough version of JS that you have Array.indexOf()
if (-1 === tempArray.indexOf(matchedPairs[i][j][0]))
tempArray.push(matchedPairs[i][j][0]);
if (-1 === tempArray.indexOf(matchedPairs[i][j][1]))
tempArray.push(matchedPairs[i][j][1]);
}
finalCombinations.push(tempArray);
}
for (i=0; i<finalCombinations.length; i++)
console.log(finalCombinations[i]);
// console.log shows that finalCombinations = [ [1,2,3], [9,10,11] ]
如果效果不明显,请使用调试器和/或铅笔和纸张进行操作。
答案 1 :(得分:1)
我必须说你的问题还不清楚,但我想我明白了。
换句话说,你所说的是: 我有一个包含一堆数字的数组,逻辑上它们代表坐标,并不是坐标是主数组中的子数组,只是看它们2乘2,但它是一个线性数组。
您想要的是检测相邻坐标并生成包含它们的新数组。
之后,您希望通过新数组并生成包含unique-elements的新数组。
那就是问题,现在是答案。首先,第二点取决于你想走多远,我认为它是x,y坐标的正常网格,但你想要去的距离是多少?以下仅适用于中间相邻,最多8个点可以与单个点相邻。
[1,1][2,1][3,1]
[1,2][2,2][3,2]
[1,3][2,3][3,3]
可能是网格的表示,如果你的主数组有[2,2]坐标,你想要构建一个以你找到的所有邻接开始的数组,就像主数组那样[3] ,2],然后你想把它添加到[2,2]的子阵列。
我真的不是在编写代码我只是要解释你可以使用的各种算法。 要构建第二个点数组,我们可以将它们称为Adjacents Arrays(AA):
第一个坐标将始终构建第一个AA 要查找邻接,您将循环通过主阵列并对每个坐标执行“邻接检查”:第二个x ==(第一个x-1,x或x + 1)和第二个y ==(第一个y-1 ,y或y + 1),如果它通过那么pop / push,如果不通过... next。 如果您通过主阵列完成循环,则表示AA已完成,您必须使用下一个坐标启动新的AA。 重复,直到主数组为空。
然后创建unique-element-array是一个非常简单的循环,我编写了一个类似的函数来执行类似的操作,但是它创建了一个包含该元素的数组以及它在数组中出现的次数(实例): / p>
function uniqueCnt( ori) { // agroups and counts unique elements of an array, scrubs '' elements
var res = []; // resulting array, ori parameter stands for original array
for( let cntA = 0; cntA < ori.length; cntA++) {
for( cntB = 0; cntB < res.length; cntB += 2) if( ori[cntA] == res[cntB]) { res[cntB + 1]++; break; } // if it matches means it's another instance then increase that element count
if( cntB == res.length && ori[cntA] != '') res.push( ori[cntA], 1); // New element found then push it and start count
}
return res; // returns the agrouped array 0:element 1:instances...
}
如果你不想要一个实例计数,那么你需要一个更简单的函数,你可以尝试修改这个。