Создание нескольких массивов на основе частоты координат в массиве

#javascript #arrays #coordinates #frequency

#javascript #массивы #координаты #частота

Вопрос:

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

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

Комментарии:

1. Это JavaScript? Вы имеете в виду использовать скобки [] везде, вместо круглых скобок (), как вы это делали?

2. У вас есть веские основания полагать, что вы всегда — или обычно — сможете разбить вещи таким образом? Что, если у вас [[1,2],[1,3],[9,3],[9,10]]? Какой результат вы ожидаете в этом случае?

3. Скобки, [], предназначены для массивов.

4. Большой массив, var A, не имеет ничего вокруг отдельных точек. на самом деле это выглядит так: 1 2 1 3 2 3 9 10 9 11 10 11 однако в коде я добавил скобки и запятую для создания «координат», чтобы с ними было легче обращаться.

5. Я думаю, что ваши требования неоднозначны…

Ответ №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. Это сработало так хорошо! Я узнал несколько вещей, изучая этот код. Спасибо за помощь.

2. Пожалуйста. Поскольку вы сказали, что изучаете мой код, обратите внимание, что я кое-что сделал с циклом for с пометкой «workingCopyLoop», который я не рекомендую для большинства циклов for, но который оказался удачным для того, как я решил вашу проблему: (1) Я изменил массив, который повторяется в течениецикл (shift () удаляет первый элемент массива и возвращает этот элемент), хотя он работал нормально, потому что каждый раз, когда я делал это (2) внутри цикла, я сбрасывал счетчик цикла на 0, чтобы снова запустить цикл, и именно поэтому…

3. (3) Я опустил «окончательное выражение» в начальном операторе for , то есть бит непосредственно перед закрывающей скобкой, который обычно увеличивает счетчик цикла (поскольку я перебирал счетчики внутри цикла). Итак, я предполагаю, что я говорю, что, вероятно, это должен был быть цикл while, но я думаю (пытаясь вспомнить вчерашний день), что он начинался как более обычный цикл for, тогда я понял, что он не совсем делает то, что я хотел, и к тому времени, когда он заработал, я не могпотрудитесь изменить его на цикл while.

Ответ №2:

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

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

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