我试图通过首先创建轴坐标来动态创建有限n维坐标系中的位置列表。系统仅将整数作为坐标值。轴坐标是AxCrd对象。 AxCrd对象有两个属性:
我试图编写一个函数,该函数接受所有生成的AxCrd对象作为输入,并输出n维空间中我尝试创建为Crd的所有位置的列表-objects。 Crd-object有两个属性:
Crd.dims是一个包含坐标所有维度句柄的数组。此数组的长度为n,即等于维数。
Crd.crds是一个包含上述尺寸的所有坐标值的数组。该数组的排序很重要,因为坐标的维度应该与坐标值具有相同的元素编号。 IE浏览器。如果尺寸" 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]));
如何在n维空间中执行此操作?
答案 0 :(得分:1)
如果我理解了您的问题,那么您需要一张包含所有维度名称的地图(称为dim_map
应为dim_map['x'] = 0; dim_map['y'] = 1;...
)。
然后,当您进行转换时,使用密钥dims
,查找index = dim_map[AxCrd.dim]
的索引,并将这些值分配给相应的元素(Crd.crds[index] = AxCrd.crd
)。
我不完全确定这是你想要的,因为你的例子似乎令人困惑。我不确定为什么你为每个AxCrd构建两个Crds或者为什么其他一些值似乎会改变。
答案 1 :(得分:1)
递归似乎是处理这类问题的正确方法。这是一个简单的递归函数,它返回结果的数组。它还将维度的名称存储在作为函数参数传递的数组中。
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;
}
此函数不会创建Crd
个对象,但您可以轻松修改它。用法示例:
var dimensions = [];
var result = rec(0, input, dimensions);
console.log(JSON.stringify(dimensions));
for (var i = 0; i < result.length; i++) {
console.log(JSON.stringify(result[i]));
}
输出(假设input
与示例中一样):
["x","y","z","d"]
[-1,-1,-1,-1]
[-1,-1,-1,1]
[-1,-1,1,-1]
[-1,-1,1,1]
[-1,1,-1,-1]
[-1,1,-1,1]
[-1,1,1,-1]
[-1,1,1,1]
[1,-1,-1,-1]
[1,-1,-1,1]
[1,-1,1,-1]
[1,-1,1,1]
[1,1,-1,-1]
[1,1,-1,1]
[1,1,1,-1]
[1,1,1,1]
答案 2 :(得分:0)
看起来您正在寻找每个子阵列或Cartesian product项目的所有可能组合。这可以递归计算:
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;
}
Ans像这样使用它:
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]);
}
上述函数在假设传递的数组是数组数组的情况下工作。没有试图检测到它。
您可以将生成的数组添加到列表中,而不是打印。我不确定为什么每次添加坐标时都会创建一个新的坐标系。难道你不应该只创建一次坐标系并传递一个参考吗?我也是第二个索林,你可能想要一个逐字母查找的地图。你的班级设计似乎不必要地复杂。
答案 3 :(得分:0)
我打算做的事情似乎几乎可以通过以下功能实现:
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; }}
结果是9×9×9×9×3×3 = 59049个成员的阵列。这个数字是正确的。但是,每个数组只有一个成员,这是一个由六个重复的“[object Object]”组成的字符串。我需要它们是六个AxCrd对象的唯一数组而不是这样的字符串。数组的顺序无关紧要。以这种方式修改这个功能难吗?
无论如何,我希望这个回复能够清楚地表明我正在做的事情。