Javascript:如何创建多维数组? (需要代码示例)

发布于 2024-12-20 10:23:24 字数 674 浏览 0 评论 0原文

我有一个 10 行、10 列的表。我想定义一个数组,我可以在其中放置一个值,例如 pos。第 5 行,第 3 列。

该值本身是一个包含更多条目的数组。而这个数组的入口也是一个数组。

示例:

Row 1, column 1:
   My text 1, Link to text 1
   My text 2, Link to text 2

Row 4, column 5:
   My text 3, Link to text 3

Row 6, column 2:
   My text 1, Link to text 1
   My text 2, Link to text 2
   My text 3, Link to text 3
   My text 4, Link to text 4

并非每个表条目都需要定义。一个表元素条目可以有多个条目。一个条目由两个值组成。文本和文本的链接。

html-table 已经定义。现在我想用上面的值(链接)填充它。

我的问题是,如何创建一个有效的数据结构,以便我可以轻松找到具有条目的表位置(也许无需循环 10 行 10 列)。对于每个条目,我想获取文本+链接列表。

以及如何访问/阅读我的定义的每个条目。 (我可以将值放入我的 html 表中。)

如果有人能给我一些如何设置这样的数据结构的代码示例,我将非常感激。

I have a table 10 rows, 10 columns. I want to define an array where I can place a value at e.g. pos. row 5, column 3.

The value itself is an array with more entries. And the entry of this array is also an array.

Example:

Row 1, column 1:
   My text 1, Link to text 1
   My text 2, Link to text 2

Row 4, column 5:
   My text 3, Link to text 3

Row 6, column 2:
   My text 1, Link to text 1
   My text 2, Link to text 2
   My text 3, Link to text 3
   My text 4, Link to text 4

Not every table entry needs to be defined. A table element entry can have multiple entries. An entry consists of two values. A text and the link for the text.

The html-table is already defined. Now I want to fill it with the values (links) above.

My problem is, how to create an efficient data structure so that I easily can find table-positions that have entries (maybe without looping 10 rows 10 columns). For each entry I want to get the list of texts + links.

And how to access/read each entry of my definition. (I have no problem placing the value to my html-table.)

I'd really appreciate if someone could give me some code-example how to set up such a data structure.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

与之呼应 2024-12-27 10:23:24
var multiArray = [ ['element 0, 0', 'element 0, 1', 'element 0, 2'], ['element 1, 0', 'element 1, 1']];

等等...

编辑
[] 中的每个符号都是一个数组,因此您只需将它们组合到另一个数组中

var multiArray = [ ['element 0, 0', 'element 0, 1', 'element 0, 2'], ['element 1, 0', 'element 1, 1']];

and so on...

EDIT
every single notation in [] is an array, so you just have to combine them into an another array

野稚 2024-12-27 10:23:24

如果内存不是问题,就使用数组的数组;

var table = [];
table.length = 10; // 10 rows;

for (var i = 0; i < array.length; i++) {
    table[i] = [];
    table[i].length = 20; // 20 columns for each row.
}

如果表很大但只使用了几个单元格,您还可以使用散列的散列:

var table = {};
table.rowCount = 10; // there're 10 rows

table[1] = {}
table[1].columnCount = 20 // 20 cells for row 1
table[1][3] = "hello world";

// visit all cells
for (var row in table) {
    for (var column in table[row] {
        console.log(table[row][column]);
    }
}

您甚至可以混合散列和数组。

Just use an array of array if the memory is not the problem;

var table = [];
table.length = 10; // 10 rows;

for (var i = 0; i < array.length; i++) {
    table[i] = [];
    table[i].length = 20; // 20 columns for each row.
}

If the table is big but only a few cells are used, you can also use a hash of hash:

var table = {};
table.rowCount = 10; // there're 10 rows

table[1] = {}
table[1].columnCount = 20 // 20 cells for row 1
table[1][3] = "hello world";

// visit all cells
for (var row in table) {
    for (var column in table[row] {
        console.log(table[row][column]);
    }
}

You can even mix hash and array.

抠脚大汉 2024-12-27 10:23:24

您可以创建一个简单的包装器来方便调用: http://jsfiddle.net/QRRXG/2/

多维数组只是另一个数组中的一个数组。因此,您可以构建一个包含 10 个数组的数组,每个数组又包含 10 个数组。然后用arr[i][j]得到一个。

项目可以表示为一个对象:

{ name: "foo", link: "bar" }

然后可以像 obj.nameobj.link 一样解析这样的项目。

var multi = (function() {
    var data = [];

    // initialize
    for(var i = 0; i < 10; i++) {
        data[i] = [];
        for(var j = 0; j < 10; j++) {
            data[i][j] = [];
        }
    }

    return {
        get: function(i, j) { // will return an array of items
            return data[i][j];
        },

        push: function(i, j, v) { // will add an item
            data[i][j].push(v);
        },

        clear: function(i, j) { // will remove all items
            data[i][j] = [];
        },

        iterateDefined: function(f) {
            for(var i = 0; i < 10; i++) {
                for(var j = 0; j < 10; j++) {
                    if(data[i][j].length > 0) {
                        f(data[i][j], i, j);
                    }
                }
            }
        }
    };
})();

您可以像这样使用它:

multi.push(2, 3, { name: "foo", link: "test1" });
multi.push(2, 3, { name: "bar", link: "test2" });

multi.push(1, 4, { name: "haz", link: "test3" });

multi.push(5, 7, { name: "baz", link: "test4" });
multi.clear(5, 7);


console.log(multi.get(2, 3)); // logs an array of 2 items
console.log(multi.get(1, 4)); // logs an array of 1 item
console.log(multi.get(5, 7)); // logs an array of 0 items

console.log(multi.get(2, 3)[0].name); // logs "foo"
console.log(multi.get(2, 3)[1].link); // logs "test2"


multi.iterateDefined(function(items, i, j) {
    console.log(items, i, j); // will log two times
});

You could create a simple wrapper to make calling convenient: http://jsfiddle.net/QRRXG/2/.

A multidimensional array is just an array in another. So you can build an array with 10 arrays which in turn have 10 arrays in each. Then get one with arr[i][j].

Items can be represented as an object:

{ name: "foo", link: "bar" }

then such an item can be parsed like obj.name and obj.link.

var multi = (function() {
    var data = [];

    // initialize
    for(var i = 0; i < 10; i++) {
        data[i] = [];
        for(var j = 0; j < 10; j++) {
            data[i][j] = [];
        }
    }

    return {
        get: function(i, j) { // will return an array of items
            return data[i][j];
        },

        push: function(i, j, v) { // will add an item
            data[i][j].push(v);
        },

        clear: function(i, j) { // will remove all items
            data[i][j] = [];
        },

        iterateDefined: function(f) {
            for(var i = 0; i < 10; i++) {
                for(var j = 0; j < 10; j++) {
                    if(data[i][j].length > 0) {
                        f(data[i][j], i, j);
                    }
                }
            }
        }
    };
})();

You can the use it like:

multi.push(2, 3, { name: "foo", link: "test1" });
multi.push(2, 3, { name: "bar", link: "test2" });

multi.push(1, 4, { name: "haz", link: "test3" });

multi.push(5, 7, { name: "baz", link: "test4" });
multi.clear(5, 7);


console.log(multi.get(2, 3)); // logs an array of 2 items
console.log(multi.get(1, 4)); // logs an array of 1 item
console.log(multi.get(5, 7)); // logs an array of 0 items

console.log(multi.get(2, 3)[0].name); // logs "foo"
console.log(multi.get(2, 3)[1].link); // logs "test2"


multi.iterateDefined(function(items, i, j) {
    console.log(items, i, j); // will log two times
});
少女情怀诗 2024-12-27 10:23:24

创建实用程序对象:

var DataTable = {
    source: [],
    setEntry: function(i,j,e) {
      var o ;
        if( !!! ( o = this.source[i] )  ) o = this.source[i] = [] ;
        o[j] = e ;
        return this ;
    },
    getEntry: function(i,j) {
      var o, e = null ;
        if( !! ( o = this.source[i] ) ) e = o[j] || null ;
      return e ;
    }
} ;

其他答案似乎建议将虚拟数组作为未使用的坐标的占位符。这虽然没有错,但却是不必要的:如果您在 JavaScript 中的 Array 上设置一个索引超出当前范围的条目,则 Array 本质上会用 < 填充代码>未定义值。

var a = [ ] ; // a length is 0
    a[1024] = 1 // a length is now 1025, a[1] is undefined

然后添加您需要的值:

DataTable.setEntry( 1, 1, ["My text 1","Link to text 1","My text 2","Link to text 2"] )
.setEntry( 4, 5, ["My text 3","Link to text 3"] ) 
//..
;

以下控制语句将返回坐标的 Array 值或 null(如果 DataTable.source不包含给定坐标的嵌套Array):

console.log("(!!) d.source: " + DataTable.getEntry(4,5) ) ;
console.log("(!!) d.source: " + DataTable.getEntry(1,1) ) ;
console.log("(!!) d.source: " + DataTable.getEntry(0,0) ) ;

在这里尝试:


更新:

这是一篇相当旧的帖子,但由于我收到了解释该代码片段的评论,因此这里有类语法的更新和更多评论:

class DataTable {

  data = [];
  
  constructor() {
    // bind methods to this instance
    this.setEntry = this.setEntry.bind(this);
    this.getEntry = this.getEntry.bind(this);
  }
  
  // set an entry at the given coordinates (row and column index pair)
  setEntry(rowIndex, columnIndex, value) {
    let row = this.data[rowIndex];
    
    // create the row lazily if it does not exist yet
    if(typeof row === 'undefined') {
      this.data[rowIndex] = [];
      row = this.data[rowIndex];
    }
    // set the value
    row[columnIndex] = value;
  }
  
  // get the entry at the given coordinates (row and column index pair)
  getEntry(rowIndex, columnIndex) {
    const row = this.data[rowIndex];
    // test if the row is defined; if not return null.
    if(typeof row === 'undefined') { return null; }
    else {
      // return the value or fall back to null
      return row[columnIndex] || null;
    }
  }

}

const d = new DataTable();
d.setEntry(1, 1, ["My text 1","Link to text 1","My text 2","Link to text 2"]);
d.setEntry(4, 5, ["My text 3","Link to text 3"]);

console.log(`d.getEntry(4, 5) = ${d.getEntry(4, 5)}`);
console.log(`d.getEntry(1, 1) = ${d.getEntry(1, 1)}`);
console.log(`d.getEntry(0, 0) = ${d.getEntry(0, 0)}`);

Create a utility Object:

var DataTable = {
    source: [],
    setEntry: function(i,j,e) {
      var o ;
        if( !!! ( o = this.source[i] )  ) o = this.source[i] = [] ;
        o[j] = e ;
        return this ;
    },
    getEntry: function(i,j) {
      var o, e = null ;
        if( !! ( o = this.source[i] ) ) e = o[j] || null ;
      return e ;
    }
} ;

The other answers seem to suggest placing dummy Arrays as placeholders for coordinates that are unused. This -- while it is not wrong -- is unnecessary: if you set an entry on an Array in JavaScript whose index exceeds the current range the Array is essentially padded with undefined values.

var a = [ ] ; // a length is 0
    a[1024] = 1 // a length is now 1025, a[1] is undefined

Then add the values you require:

DataTable.setEntry( 1, 1, ["My text 1","Link to text 1","My text 2","Link to text 2"] )
.setEntry( 4, 5, ["My text 3","Link to text 3"] ) 
//..
;

The following control statements will return the value of the Arrays of the coordinates or null (if DataTable.source does not contain a nested Array for the given coordinates):

console.log("(!!) d.source: " + DataTable.getEntry(4,5) ) ;
console.log("(!!) d.source: " + DataTable.getEntry(1,1) ) ;
console.log("(!!) d.source: " + DataTable.getEntry(0,0) ) ;

Try it here:


UPDATE:

This is a pretty old post, but since I received a comment to explain the snippet, here's an update with class syntax and a few more comments:

class DataTable {

  data = [];
  
  constructor() {
    // bind methods to this instance
    this.setEntry = this.setEntry.bind(this);
    this.getEntry = this.getEntry.bind(this);
  }
  
  // set an entry at the given coordinates (row and column index pair)
  setEntry(rowIndex, columnIndex, value) {
    let row = this.data[rowIndex];
    
    // create the row lazily if it does not exist yet
    if(typeof row === 'undefined') {
      this.data[rowIndex] = [];
      row = this.data[rowIndex];
    }
    // set the value
    row[columnIndex] = value;
  }
  
  // get the entry at the given coordinates (row and column index pair)
  getEntry(rowIndex, columnIndex) {
    const row = this.data[rowIndex];
    // test if the row is defined; if not return null.
    if(typeof row === 'undefined') { return null; }
    else {
      // return the value or fall back to null
      return row[columnIndex] || null;
    }
  }

}

const d = new DataTable();
d.setEntry(1, 1, ["My text 1","Link to text 1","My text 2","Link to text 2"]);
d.setEntry(4, 5, ["My text 3","Link to text 3"]);

console.log(`d.getEntry(4, 5) = ${d.getEntry(4, 5)}`);
console.log(`d.getEntry(1, 1) = ${d.getEntry(1, 1)}`);
console.log(`d.getEntry(0, 0) = ${d.getEntry(0, 0)}`);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文