5

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.

ROMANIA_engineer
57.1k30 gold badges211 silver badges207 bronze badges
asked Dec 10, 2011 at 11:38

4 Answers 4

3
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

answered Dec 10, 2011 at 11:44
Sign up to request clarification or add additional context in comments.

3 Comments

it's not important to have the same length for all columns in JS, I like it
Am I right that using this notation, I have to define EVERY table row+column, even if I do not need a certain field?
@Enkidu what do you mean by "even if I do not need a certain field" ?
1

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.

answered Dec 10, 2011 at 11:42

1 Comment

Your second example is what I was already experimenting with. I have no problem attaching a simple string e.g. "table[1][3] = "hello world";". But I have my problems attaching an array. I tried with table[1][3] = new Array( new Array( 'text1', 'link1'), new Array( 'text2', 'link2' ) ); but I do not know how to access the values... Btw, instead of "new Array()", can I also write [ a, b ]?
1

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
});
answered Dec 10, 2011 at 11:45

2 Comments

This looks really smart! :) But my problem is that I do not want to access a certain field in the table but to just get the values of the fields defined. (There are maybe only 20 of 100 with values.)
Great! Tnx! Seems to be what I want! :)
1

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

answered Dec 10, 2011 at 15:53

3 Comments

Tnx. I never used this kind of coding before. But it seems it is exactly what I am searching for.
Exactly what i was looking for. A bit difficult to understand, if possible can you please explain setEntry and getEntry of this part !!!.
@Dileephell I've added an update using class syntax and added a few comments.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.