2011-10-03 34 views
1

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

我可以得到幫助嗎?

+0

這是JavaScript的嗎?你的意思是到處使用括號[],而不是像你一樣使用括號()? – BobS

+0

你是否有充分的理由認爲你將永遠 - 或通常 - 能夠以這種方式打破這些事情?如果你有[[1,2],[1,3],[9,3],[9,10]]會怎麼樣?在這種情況下你期望的結果是什麼? – BobS

+0

JavaScript,是的! – JsusSalv

回答

1

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

如果不是很明顯這是如何工作,用調試器遵循它通過和/或鉛筆和紙。

+0

這工作得很好!在學習這些代碼時,我學到了很多東西。感謝您的幫助。 – JsusSalv

+0

不客氣。既然你說你正在研究我的代碼注意事項,我用for循環標記了「workingCopyLoop」,我不建議用於_most_ for循環,但碰巧解決了我碰巧解決問題的方式:( 1)我修改了在循環內迭代的數組(shift()移除數組的第一個項並返回該項),雖然它工作正常,因爲每次我在循環內部完成它(2),我將循環計數器重置爲0這也是爲什麼... – nnnnnn

+0

(3)我省略了最初的語句中的「最終表達式」,即剛好在右括號之前的那個位,它通常遞增循環計數器(因爲我在擺弄循環內的計數器)。所以我想我說的是它可能應該是一段時間的循環,但我認爲(試圖記住回到昨天)它開始作爲一個更傳統的循環,然後我意識到它不是做什麼我想,當我有它的工作時間,我不能被麻煩改變它到一個while循環。 – nnnnnn

1

我必須說你的問題還不太清楚,但我想我明白了。

換句話說你在說的是: 我有一個數組包含一堆數字,邏輯上它們表示座標,它不是坐​​標是主數組內的子數組,只是看它們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。 重複,直到主數組爲空。

然後創建unique-element-array是一個相當簡單的循環,我寫了一個類似的函數來做類似的事情,但是它創建了一個包含該元素的數組以及它出現在數組(實例)中的次數:

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

如果你不想實例的計數,那麼你就需要一個更簡單的功能,你可以嘗試修改此一個。