1

Javascript には、可変数の行と列を持つマトリックスがあり、これを多次元配列に格納したいと考えています。

問題は、マトリックスにも負のインデックスを持つ余分な 3 列と 3 つの余分な行が必要なことです。したがって、10x10 の行列の結果は、-3 から 9 までのインデックスを持つ 13x13 の配列になるはずです。

次のように配列を定義します。

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

これはこれを行う正しい方法ですか?それとももっと良い方法がありますか?

4

3 に答える 3

3

負の数の属性を作成することはできますが、Javascript の疑似配列マジックの一部が失われます。特に、matrix.length要素が 13 個あるにもかかわらず、 は 10 のままです。そして、一般的に、コードを読んでいる人は驚くかもしれません。

配列インデックスから必要な値を取得するためにオフセットを定義した方がよい場合があり、その逆も同様です。

var offset = 3
for (var x=-3; x<numberofcolumns; x++) {
   matrix[x+offset] = []
}
于 2012-10-14T23:08:11.143 に答える
1

これが直感的でない Array の使用であるという Mark Reed の指摘に同意します。サブクラスは大丈夫だと思います。ここのチュートリアルに従って、Array をサブクラス化し、ネイティブのブラケット表記を維持し、length() などのメソッドをオーバーライドして、適切な値を与えることができます。サブクラス化には、コードを読んでいる人に、日常の配列以外に何かが起こっていることを明確にするという追加の利点があります。

于 2012-10-14T23:32:15.413 に答える
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"); 
    });

デモ: http://jsfiddle.net/uTVUP/

于 2012-10-14T23:52:42.240 に答える