【问题标题】:Create multiple arrays based on frequency of coordinates in an array根据数组中坐标的频率创建多个数组
【发布时间】:2011-11-29 14:54:29
【问题描述】:

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

我可以得到帮助吗?

【问题讨论】:

  • 这是 JavaScript 吗?你的意思是在任何地方都使用括号 [],而不是像你一样使用括号 ()?
  • 您是否有充分的理由认为您将始终(或通常)能够以这种方式分解事物?如果你有 [[1,2],[1,3],[9,3],[9,10]] 怎么办?在这种情况下,您期望的结果是什么?
  • 方括号 [] 用于数组。
  • 大数组 var A 在各个点周围没有任何内容。它实际上看起来像这样:1 2 1 3 2 3 9 10 9 11 10 11 但是,在代码中我添加了括号和逗号来创建“坐标”,以便更容易处理。
  • 我认为你的要求是模棱两可的......

标签: javascript arrays coordinates frequency


【解决方案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] ]

如果它的工作原理不明显,请使用调试器和/或铅笔和纸完成。

【讨论】:

  • 这很好用!在研究这段代码时,我学到了几件事。感谢您的帮助。
  • 不客气。既然您说您正在研究我的代码,请注意我使用标记为“workingCopyLoop”的 for 循环做了一些事情,我不建议 most for 循环使用,但它恰好适合我的方式碰巧解决了您的问题:(1)我修改了在循环中迭代的数组(shift()删除数组的第一项并返回该项),尽管它工作正常,因为每次我在循环中这样做(2)我将循环计数器重置为 0 以再次启动循环,这也是为什么...
  • (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]的子数组中。

我真的不是在编写代码,我只是要解释你可以使用的各种算法。 要构建第二个点数组,我们可以将它们称为 Adjacents Arrays (AA):

第一个坐标将始终构建第一个 AA 要找到相邻点,您将遍历主阵列并对每个坐标执行“邻接检查”,即:第二个 x ==(第一个 x-1,x 或 x+1)和第二个 y ==(第一个 y-1 , y 或 y+1),如果通过则 pop/push,如果不通过... next。 如果您通过主阵列完成循环,则意味着 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...
}

如果你不想要实例计数,那么你需要一个更简单的函数,你可以尝试修改这个。

【讨论】:

    猜你喜欢
    • 2019-04-02
    • 1970-01-01
    • 2013-08-28
    • 1970-01-01
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 2013-08-17
    相关资源
    最近更新 更多