如何动态创建具有负索引的多维数组?

时间:2012-10-14 23:00:36

标签: javascript multidimensional-array

在Javascript中,我有一个矩阵,其中包含可变数量的行和列,我希望将其存储在多维数组中。

问题是我在矩阵中还需要额外的3列和3行额外的索引。因此,10x10矩阵的结果应该是13x13阵列,索引从-3到9。

我用以下代码定义数组:

  var numberofcolumns = 10;
  var numberofrows = 10;
  var matrix = [];
  for (var x = -3; x < numberofcolumns; x++) {
    matrix[x] = [];
  }

这是正确的方法吗?或者有更好的方法吗?

3 个答案:

答案 0 :(得分:3)

虽然你可以创建负数的属性,但是你会丢失一些Javascript的伪阵列魔法。特别是,matrix.length仍然是10,即使它有13个元素。对于阅读它的人来说,一般来说代码可能会令人惊讶。

您可能最好定义一个偏移量以从数组索引中获取所需的值,反之亦然:

var offset = 3
for (var x=-3; x<numberofcolumns; x++) {
   matrix[x+offset] = []
}

答案 1 :(得分:1)

我同意Mark Reed关于这是对Array的不直观使用的观点。我认为子类是有序的。您可以按照教程here继承Array,保留本机括号表示法,并覆盖length()等方法,以便它们给出合理的值。子类化还有一个额外的好处,就是让那些阅读你的代码的人清楚地知道除了你的日常数组之外的其他东西。

答案 2 :(得分:1)

您可以将矩阵定义为对象。您将失去一些阵列功能,但您仍然可以访问matrix[-3],例如。

  var numberofcolumns = 10;
  var numberofrows = 10;
  var matrix = {};
  for (var x = -3; x < numberofcolumns; x++) {
    matrix[x] = [];
  }
  for (x in matrix) {
    console.log(matrix[x]);
  }

或者您可以从对象或数组开始定义自己的类并从那里开始工作。这是让你入门的东西:

function Matrix() { };

Matrix.prototype.LBound = function()
{
    var n;
    for (i in this) {
        if (!isNaN(i) && (isNaN(n) || n > i))
            n = parseInt(i);
    }
    return n;
};

Matrix.prototype.UBound = function()
{
    var n;
    for (i in this) {
        if (!isNaN(i) && (isNaN(n) || n < i))
            n = parseInt(i);
    }
    return n;
};

Matrix.prototype.length = function()
{
    var length = this.UBound() - this.LBound();
    return isNaN(length) ? 0 : length+1;
};

Matrix.prototype.forEach = function(callback, indexes)
{
    if (!indexes) var indexes = [];
    for (var i = this.LBound(); i <= this.UBound() ; i++)
    {
        indexes[Math.max(indexes.length-1, 0)] = i;
        callback(this[i], indexes);
        if (this[i] instanceof Matrix)
        {
            var subIndexes = indexes.slice();
            subIndexes.push("");
            this[i].forEach(callback, subIndexes);
        }
    }
};

Matrix.prototype.val = function(newVal)
{
    if (newVal) 
    {
        this.value = newVal;
        return this;
    }
    else
    {
        return this.value;
    }
};

然后你就这样创建矩阵了

var numberofcolumns = 10;
var numberofrows = 10;

var matrix = new Matrix();

for (var i = -3; i < numberofcolumns; i++) {
    matrix[i] = new Matrix();
        for (var j = -4; j < numberofrows; j++) {
            matrix[i][j] = new Matrix();
            matrix[i][j].val("test " + i + " " + j);
        }
}

你可以在它上面运行一些很酷的功能

console.log("Upper bound: " + matrix.LBound());
console.log("Lower bound: " + matrix.UBound());
console.log("Length: " + matrix.length());

matrix.forEach(function(item, index) 
    {
        if (item.val()) 
            console.log("Item " + index + " has the value \"" + item.val() + "\""); 
        else
            console.log("Item " + index + " contains " + item.length() + " items"); 
    });

DEMO:http://jsfiddle.net/uTVUP/