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

发布于 2024-12-07 20:23:20 字数 459 浏览 0 评论 0原文

使用 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]

我可以获得帮助吗?

Using JavaScript, I'd like to split one big array of coordinates into smaller arrays based on coinciding points. I am not 100% sure how to write the following in code but it describes what I'm attempting to achieve:

  1. Iterate through the array

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

  2. Combine the pairs that contain any matching/identical coordinate points:

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

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

  3. Combine the matching/identical points and create new, smaller arrays from the combinations in point #2

    var D = [1,2,3]

    var E = [9,10,11]

Can I get help please?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暗恋未遂 2024-12-14 20:23:20

工作答案: 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] ]

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

Working answer: http://jsfiddle.net/y3h9L/

OK, so if I understand the requirement A is a one-dimensional array that is assumed to have an even number of elements in x,y pairs.

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] ]

I've made no effort to pretty-up or optimise the following code, but it works:

// 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] ]

If it's not obvious how this works, follow it through with a debugger and/or pencil and paper.

冷血 2024-12-14 20:23:20

我必须说你的问题相当不清楚,但我想我明白了。

换句话说,你所说的是:
我有一个包含一堆数字的数组,逻辑上它们代表坐标,这并不是说坐标是主数组内的子数组,只是将它们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) AND 第二个 y == (第一个 y-1 、y 或 y+1),如果通过则弹出/推入,如果没有通过...下一步。
如果您完成主数组的循环,则意味着 AA 已完成,您必须使用下一个坐标开始新的 AA。
重复直到主数组为空。

然后创建唯一元素数组是一个非常简单的循环,我编写了一个类似的函数,它执行类似的操作,但它使用该元素创建一个数组以及它在数组(实例)中出现的次数:

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

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

I must say your question is rather unclear, but i think i got it.

In other words what you're saying is:
I have an array containing a bunch of numbers, logically they represent coordinates, it's not that the coordinates are subarrays inside the master array, is just looking them 2 by 2, but it's a linear array.

What you want is something that detects coordinates that are adjacent and generate a new array containing them.

After that you want to go thru the new arrays and generate new arrays containing unique-elements.

Well that's the question, now the answer. First, the second point depends on how far you want to go, i'm thinking it's anormal grid of x,y coordinates, but how adjacent you want to go? The following just applies to the inmediate adjacent, up to 8 points can be adjacent to a single point.

[1,1][2,1][3,1]
[1,2][2,2][3,2]
[1,3][2,3][3,3]

May that be a representation of the grid, if your master array has the [2,2] coordinate, you want to build an array that begins with that one and all adjacents you find, lets say like master array has [3,2], then you want to add it to the subarray of [2,2].

I'm really not writing the code i'm just gonna explain sorts of algorithm you could use.
To build the second point arrays, lets call them Adjacents Arrays (AA) you could:

First coordinate will always build the first AA
To find adjacents you will cycle thru the master array and perform an "Adjacency Check" to every coordinate which would be: second x == ( first x-1, x or x+1) AND second y == ( first y-1, y or y+1), if it passes then pop/push, if not... next.
In case you finish cycling thru the master array means that AA is complete, and you have to start a new AA with the next coordinate.
Repeat until master array is empty.

Then to create the unique-element-array is quite a simple cycle, i wrote a similar function that does something like that but it creates an array with the element and how many times it appears in the array (instances):

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

If you don't want a count of instances, then you would need an even simpler function, you could try modify this one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文