开发者

Create multiple arrays based on frequency of coordinates in an array

开发者 https://www.devze.com 2023-04-09 21:04 出处:网络
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 attem

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,开发者_Python百科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?


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号