【问题标题】:Javascript: how to create a multi-dimensional array? (Code example needed)Javascript:如何创建多维数组? (需要代码示例)
【发布时间】:2011-12-10 11:38:11
【问题描述】:

我有一个 10 行 10 列的表。我想定义一个数组,我可以在其中放置一个值,例如位置第 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 表中。)

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

【问题讨论】:

    标签: javascript arrays data-structures multidimensional-array


    【解决方案1】:
    var multiArray = [ ['element 0, 0', 'element 0, 1', 'element 0, 2'], ['element 1, 0', 'element 1, 1']];
    

    等等……

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

    【讨论】:

    • JS中所有列的长度不一样,我喜欢
    • 我是否正确,使用这种表示法,我必须定义每个表行+列,即使我不需要某个字段?
    • @Enkidu “即使我不需要某个领域”是什么意思?
    【解决方案2】:

    如果内存不是问题,只需使用数组数组即可;

    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.
    }
    

    如果表格很大但只使用了几个单元格,也可以使用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]);
        }
    }
    

    您甚至可以混合使用哈希和数组。

    【讨论】:

    • 你的第二个例子是我已经在试验的。我没有问题附加一个简单的字符串,例如"table[1][3] = "你好世界";".但是我在附加一个数组时遇到了问题。我试过 table[1][3] = new Array( new Array( 'text1', 'link1'), new Array( 'text2', 'link2' ) );但我不知道如何访问这些值...顺便说一句,我可以写 [a, b] 而不是“new Array()”吗?
    【解决方案3】:

    您可以创建一个简单的包装器以方便调用: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
    });
    

    【讨论】:

    • 这看起来很聪明! :) 但我的问题是我不想访问表中的某个字段,而只想获取定义的字段的值。 (100 个值中可能只有 20 个。)
    • 太棒了!天呐!似乎是我想要的! :)
    【解决方案4】:

    创建一个实用程序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 ;
        }
    } ;
    

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

    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"] ) 
    //..
    ;
    

    以下控制语句将返回坐标的Arrays 或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) ) ;
    

    在这里试试:


    更新:

    这是一篇相当老的帖子,但由于我收到了解释 sn-p 的评论,因此这里更新了类语法和更多 cmets:

    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)}`);

    【讨论】:

    • Tnx。我以前从未使用过这种编码。但它似乎正是我正在寻找的。​​span>
    • 正是我想要的。有点难理解,可以的话请解释一下这部分的setEntry和getEntry!!!。
    • @Dileephell 我添加了一个使用类语法的更新并添加了一些 cmets。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-02
    • 2011-05-19
    • 2012-05-14
    • 1970-01-01
    • 2019-12-11
    • 1970-01-01
    相关资源
    最近更新 更多