#javascript #arrays #coordinates #frequency
#javascript #массивы #координаты #частота
Вопрос:
Используя JavaScript, я хотел бы разделить один большой массив координат на меньшие массивы на основе совпадающих точек. Я не уверен на 100%, как написать следующее в коде, но оно описывает то, чего я пытаюсь достичь:
-
Итерация по массиву
var A = [(1,2)(1,3)(2,3)(9,10)(9,11)(10,11)];
-
Объедините пары, которые содержат любые совпадающие / идентичные координатные точки:
var B = (1,2)(1,3)(2,3)
var C = (9,10)(9,11)(10,11)
-
Объедините совпадающие / идентичные точки и создайте новые, меньшие массивы из комбинаций в пункте #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...
}
Если вам не нужно количество экземпляров, тогда вам понадобится еще более простая функция, вы можете попробовать изменить эту.