根据数组中坐标的频率创建多个数组

Create multiple arrays based on frequency of coordinates in an array

本文关键字:数组 创建 频率 坐标      更新时间:2023-09-26

使用JavaScript,我想根据重合点将一个大的坐标数组分成更小的数组。我不是100%确定如何在代码中编写以下内容,但它描述了我想要实现的目标:

  1. 遍历数组

    var A = [(1,2)(1,3)(2,3)(9,10)(9,11)(10,11)];

  2. 合并包含任何匹配/相同坐标点的对:

    var B = (1,2)(1,3)(2,3)

    var C = (9,10)(9,11)(10,11)

  3. 组合匹配/相同的点,并从点#2的组合中创建新的更小的数组

    var D = [1,2,3]

    var E = [9,10,11]

我能得到帮助吗?

实际答案: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] ]

如果它的工作原理不明显,请使用调试器和/或铅笔和纸来完成它。

我得说你的问题不太清楚,但我想我懂了。

换句话说,你的意思是:我有一个数组,包含一串数字,逻辑上它们代表坐标,坐标并不是主数组中的子数组,只是2乘2,但它是一个线性数组

你想要的是检测相邻坐标并生成包含它们的新数组。

之后,您需要遍历新数组并生成包含唯一元素的新数组。

这就是问题所在,现在是答案。首先,第二个点取决于你想要走多远,我认为它是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]

我真的没有写代码,我只是想解释一下你可以使用的算法。为了构建第二个点数组,我们将其称为邻接数组(AA),您可以:

第一个坐标将始终构建第一个AA为了找到邻接点,你将循环遍历主数组并对每个坐标执行"邻接检查",这将是:第二个x ==(第一个x-1, x或x+1)和第二个y ==(第一个y-1, y或y+1),如果它通过,则弹出/推,如果没有……下一个。如果您完成了对主数组的循环,则意味着AA已经完成,您必须从下一个坐标开始新的AA。重复,直到主数组为空。

然后创建unique-element-array是一个相当简单的循环,我写了一个类似的函数,做类似的事情,但它创建一个数组与元素和它在数组中出现的次数(实例):

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...
}

如果您不想要实例计数,那么您将需要一个更简单的函数,您可以尝试修改这个函数