Javascript 从轴向坐标动态创建具有整数坐标的有限n维坐标系

Javascript 从轴向坐标动态创建具有整数坐标的有限n维坐标系,javascript,arrays,algorithm,dynamic,dimensions,Javascript,Arrays,Algorithm,Dynamic,Dimensions,我试图通过首先创建轴向坐标,在有限的n维坐标系中动态创建一个位置列表。系统只有整数作为坐标值。轴向坐标是AxCrd对象。AxCrd对象有两个属性: AxCrd.dim是坐标标注的句柄或名称。例如,“x”或“y” AxCrd.crd是坐标的值。这是一个整数。例如,-4或3 我试着编写一个函数,它接受所有生成的AxCrd对象作为输入,并输出我试图创建为Crd对象的n维空间中所有位置的列表。Crd对象有两个属性: Crd.dims是一个数组,包含坐标的所有标注句柄。此数组的长度为n,即等于维数 Crd

我试图通过首先创建轴向坐标,在有限的n维坐标系中动态创建一个位置列表。系统只有整数作为坐标值。轴向坐标是AxCrd对象。AxCrd对象有两个属性:

  • AxCrd.dim是坐标标注的句柄或名称。例如,“x”或“y”
  • AxCrd.crd是坐标的值。这是一个整数。例如,-4或3
  • 我试着编写一个函数,它接受所有生成的AxCrd对象作为输入,并输出我试图创建为Crd对象的n维空间中所有位置的列表。Crd对象有两个属性:

  • Crd.dims是一个数组,包含坐标的所有标注句柄。此数组的长度为n,即等于维数

  • Crd.crds是一个数组,包含上述维度的所有坐标值。该数组的顺序很重要,因为坐标的维度应该与坐标值具有相同的元素编号。即,如果尺寸“z”是第二个元素,则crds[2]是尺寸“z”的坐标值

  • 例如,假设我使用以下构造函数:

    function AxCrd(dim,crd) { this.dim = dim, this.crd = crd }
    function Crd(dims,crds) { this.dims = dims, this.crds = crds }
    
    在我的实际预期用途中,大多数维度都有九个值:四个负值、四个正值和一个零值。但为了简单起见,让我们假设我有三个维度:

    var input = [];
    input.push(new AxCrd("x", -1));
    input.push(new AxCrd("x", 1));
    input.push(new AxCrd("y", -1));
    input.push(new AxCrd("y", 1));
    input.push(new AxCrd("z", -1));
    input.push(new AxCrd("z", 1));
    input.push(new AxCrd("d", -1));
    input.push(new AxCrd("d", 1));
    
    如您所见,有三个维度,每个维度只有两个坐标值。我正在尝试编写一个函数,在给定上述输入的情况下,该函数将创建新的Crd对象,如下所示:

    var ret = [];
    ret.push(new Crd(["x","y","z","d"],[-1,-1,-1,-1]));
    ret.push(new Crd(["x","y","z","d"],[ 1,-1,-1,-1]));
    ret.push(new Crd(["x","y","z","d"],[-1, 1,-1,-1]));
    ret.push(new Crd(["x","y","z","d"],[ 1, 1,-1,-1]));
    ret.push(new Crd(["x","y","z","d"],[-1,-1, 1,-1]));
    ret.push(new Crd(["x","y","z","d"],[ 1,-1, 1,-1]));
    ret.push(new Crd(["x","y","z","d"],[-1, 1, 1,-1]));
    ret.push(new Crd(["x","y","z","d"],[ 1, 1, 1,-1]));
    ret.push(new Crd(["x","y","z","d"],[-1,-1,-1, 1]));
    ret.push(new Crd(["x","y","z","d"],[ 1,-1,-1, 1]));
    ret.push(new Crd(["x","y","z","d"],[-1, 1,-1, 1]));
    ret.push(new Crd(["x","y","z","d"],[ 1, 1,-1, 1]));
    ret.push(new Crd(["x","y","z","d"],[-1,-1, 1, 1]));
    ret.push(new Crd(["x","y","z","d"],[ 1,-1, 1, 1]));
    ret.push(new Crd(["x","y","z","d"],[-1, 1, 1, 1]));
    ret.push(new Crd(["x","y","z","d"],[ 1, 1, 1, 1]));
    
    var input = [
        [-1, 1],    // x
        [-1, 1],    // y
        [-1, 1],    // z
        [-1, 1],    // d
    ];
    
    var prod = product(input);
    
    for (var i = 0; i < prod.length; i++) {
        console.log(i, prod[i]);
    }
    

    如何在n维空间中实现这一点?

    如果我理解你的问题,你需要一个所有维度名称到其索引的映射(称之为
    dim\u-map
    应该是
    dim\u-map['x']=0;dim\u-map['y']=1;…
    )。 然后,当您进行转换时,使用键as
    dims
    ,查找
    index=dim\u map[AxCrd.dim]
    的索引,并将该值分配给相应的元素(
    Crd.crds[index]=AxCrd.Crd


    我不能完全肯定这是你想要的,因为你的例子看起来很混乱。我不知道为什么要为每个AxCrd构造两个CRD,或者为什么其他一些值似乎会发生变化。

    递归似乎是处理此类问题的正确方法。下面是一个简单的递归函数,它返回点数组作为结果。它还存储作为函数参数传递的数组中的维度名称

    function rec(i, input, dimensions)
    {
       // find the name of the current dimension
       var currentd = input[i].dim;
    
       dimensions.push(currentd);
    
       // find how many elements in the current dimension
       var j = i;
       while (j < input.length && input[j].dim == currentd) ++j;
    
       // create a tail of results
       var tail = [];
       if (j < input.length) {
          tail = rec(j, input, dimensions);
       }
    
       // create a result by appending tail to all possible coordinates in the current dimension
       var result = [];
       for (; i < j; i++) {
           if (tail.length == 0) {
               result.push([input[i].crd]);
           } else {
               for (var k = 0; k < tail.length; k++) {
                   result.push([input[i].crd].concat(tail[k]));
               }
           }
       }
       return result;
    }
    
    输出(假设
    input
    与示例中相同):


    看起来好像您正在查找每个子阵列的所有可能的项目组合,或者。这可以递归计算:

    function product(array) {
        if (array.length == 0) return [[]];
    
        var head = array[0];
        var tail = product(array.slice(1));
        var res = [];
    
        for (var i = 0; i < head.length; i++) {
            for (var j = 0; j < tail.length; j++) {
                res.push([head[i]].concat(tail[j]));
            }
        }
    
        return res;
    }
    
    函数产品(数组){
    if(array.length==0)返回[];
    变量头=数组[0];
    var tail=乘积(array.slice(1));
    var-res=[];
    对于(变量i=0;i
    Ans是这样使用的:

    var ret = [];
    ret.push(new Crd(["x","y","z","d"],[-1,-1,-1,-1]));
    ret.push(new Crd(["x","y","z","d"],[ 1,-1,-1,-1]));
    ret.push(new Crd(["x","y","z","d"],[-1, 1,-1,-1]));
    ret.push(new Crd(["x","y","z","d"],[ 1, 1,-1,-1]));
    ret.push(new Crd(["x","y","z","d"],[-1,-1, 1,-1]));
    ret.push(new Crd(["x","y","z","d"],[ 1,-1, 1,-1]));
    ret.push(new Crd(["x","y","z","d"],[-1, 1, 1,-1]));
    ret.push(new Crd(["x","y","z","d"],[ 1, 1, 1,-1]));
    ret.push(new Crd(["x","y","z","d"],[-1,-1,-1, 1]));
    ret.push(new Crd(["x","y","z","d"],[ 1,-1,-1, 1]));
    ret.push(new Crd(["x","y","z","d"],[-1, 1,-1, 1]));
    ret.push(new Crd(["x","y","z","d"],[ 1, 1,-1, 1]));
    ret.push(new Crd(["x","y","z","d"],[-1,-1, 1, 1]));
    ret.push(new Crd(["x","y","z","d"],[ 1,-1, 1, 1]));
    ret.push(new Crd(["x","y","z","d"],[-1, 1, 1, 1]));
    ret.push(new Crd(["x","y","z","d"],[ 1, 1, 1, 1]));
    
    var input = [
        [-1, 1],    // x
        [-1, 1],    // y
        [-1, 1],    // z
        [-1, 1],    // d
    ];
    
    var prod = product(input);
    
    for (var i = 0; i < prod.length; i++) {
        console.log(i, prod[i]);
    }
    
    var输入=[
    [-1,1],//x
    [-1,1],//y
    [-1,1],//z
    [-1,1],//d
    ];
    var prod=产品(输入);
    对于(变量i=0;i
    上述函数是在假定传递的数组是数组数组的情况下工作的。没有人试图检测到这一点


    您可以将生成的数组添加到列表中,而不是打印。我不知道为什么每次添加坐标时都要创建一个新的坐标系。你不应该只创建一次坐标系并传递一个对它的引用吗?我还支持Sorin,因为您可能需要一个按字母查找维度的映射。您的类设计似乎不必要地复杂。

    我打算做的几乎是通过以下函数实现的:

    function makeAllCoordinates(arr) {
      if (arr.length === 0) { return []; }
      else if (arr.length === 1) { return arr[0]; }
      else {
        var result = [];
        var allCases = makeAllCoordinates(arr.slice(1));
        for (var c in allCases) {
          for (var i = 0; i < arr[0].length; i++) {
            result.push((arr[0][i] + allCases[c]).split(",")); }}
        return result; }}
    
    函数makeAllCoordinates(arr){
    如果(arr.length==0){return[];}
    如果(arr.length==1){返回arr[0];}
    否则{
    var结果=[];
    var allCases=makeAllCoordinates(arr.slice(1));
    用于(所有情况下的var c){
    对于(var i=0;i
    结果是一个9×9×9×9×3×3=59049个成员的数组。这个数字是正确的。但是,每个数组只有一个成员,这是一个由“[object]”的六个重复组成的字符串。我需要它们是六个AxCrd对象的唯一数组,而不是这样的字符串。数组的顺序无关紧要。以这种方式修改此函数是否困难


    在任何情况下,我希望这个回答澄清了我试图做什么的模糊性。

    在我正在创建的“游戏”或人工智能中,每个坐标都应该有“道德价值”。你可能想把它想象成“分数”。也就是说,玩家通过移动或被移动到某个坐标来获得某个分数。我想预先计算这些分数,以便更容易为计算机编写代码,从而找到最佳的移动方式。我打算把预先计算的分数作为CRD对象的属性添加。如果你把结果看作数组,而不是字符串:<代码>结果.Press([ARR〔0〕[i]).CONAT(ALORACTS [C]);<代码>?当你发布这个答案时,另外两个答案已经发布了或多或少相同的代码。如果你只是想澄清问题,请编辑原始问题。因此,您可以回答自己的问题,但前提是这些问题是真正和独特的解决方案。