Создать несколько массивов на основе частоты координат в массиве - PullRequest
1 голос
/ 03 октября 2011

Используя 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]

Могу ли я получить помощь, пожалуйста?

Ответы [ 2 ]

1 голос
/ 03 октября 2011

Я должен сказать, что ваш вопрос довольно неясен, но я думаю, что получил его.

Другими словами, вы говорите: у меня есть массив, содержащий кучу чисел, логически они представляют координаты,дело не в том, что координаты являются подмассивами внутри мастер-массива, просто они выглядят 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].

Я действительно не пишу код, я просто собираюсь объяснить, какой алгоритм вы можете использовать.Чтобы построить массивы второй точки, давайте назовем их массивами Adjacents (AA), которые вы могли бы:

Первая координата всегда будет строить первый AA. Чтобы найти смежные объекты, вы будете циклически перемещаться по мастер-массиву и выполнять «проверку смежности» длякаждая координата, которая будет: вторая x == (первая x-1, x или x + 1) и вторая y == (первая y-1, y или y + 1), если она проходит, то pop / push, если нет... следующий.В случае, если вы закончите цикл через главный массив, это означает, что 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...
}

Если вам не нужно количество экземпляров, вам понадобится еще более простая функция, вы можете попробовать изменить эту.

1 голос
/ 03 октября 2011

Рабочий ответ: http://jsfiddle.net/y3h9L/

ОК, поэтому, если я понимаю, требование А - это одномерный массив, в котором предполагается, что в парах 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] ]

Если неясно, как это работает, выполните отладчик и / или карандаш и бумагу.

...