Reputation: 7269
UPDATE — I will try to explain it again
I need to do next:
Firstly, I need to draw graph on web-page. I use Graph Dracula Library (don't pay much attention to it, my answer is not about it, I just said it, so question will be full). Secondy, I am working with array of arrays.
When I add 1 vertex to page, I will have to add 1 row into array of arrays and 1 column to each old row of array of arrays. When I add edge between two vertexes I will have to UPDATE array of arrays. When I delete vertex, I will have to delete row, connected with this vertex, and delete column, connected to this vertex, in each row in array of arrays.
EXAMPLES:
1 Page is blank, array of arrays is:
[ ]
2 Add 3 vertexes:
Page is:
Matrix (array of arrays) is:
[
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
]
3 Delete 2nd vertex:
Page is:
Matrix is:
[
[0, 0],
[0, 0]
]
Pay attention, that vertex on page are 1
and 3
, but in matrix there are only 2 rows/columns WHICH ARE NOT CONNECTED to page. So connection losted. Now 3
vertex on page is 2
nd column in each element/row in matrix.
4 For example, adding 1 more vertex.
In page:
Matrix is:
[
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
]
We have 1
, 3
and 4
vertexes on page, but only 3 rows/columns in matrix. 2nd row/column belongs to 3
vertex on page, 3rd row/column of matrix belongs to 4
vertex on page.
5 etc etc etc. There are no connection between matrix and page, so my programm works not correcly.
Problem
I can get access to vertex on page only by its name. Like 1
or 3
. So I must:
Update 50% of dracula's code (it is impossible for me)
or
Create and work with matrix with another methods. I think assoc matrix will solve my problem, but I don't know how to build/work with assoc matrix. Thats my question. How to do this? Or, if assoc array is not a good idea, give me example how to work with objects, please.
I need something like this:
// adding 1, 2, 3 vertexes
deleteVertex('3'); // this will delete both `3` vertex on page and in matrix
addVertex(); // this will add 4 (!) vertex on page and 4 vertex to matrix
Help me please!
P.S.: You can get see example of how I work with matrix on OLD QUESTION part.
OLD QUESTION
I have next problem. I need to create dynamic array of arrays. I am building graph creator (programm to draw graphs).
I am working with javascript.
How I work with array of arrays. On first call vertexCount
is 0.
// 1. Upgrade old rows and add 1 new column to each
for (var i = 0; i < vertexCount; i++)
{
weightArray[i][vertexCount] = 0;
}
// 2. Add new row
weightArray[vertexCount] = [];
// 3. Fill this row with zeros
for (var i = 0; i <= vertexCount; i++)
{
weightArray[vertexCount][i] = 0;
}
All working fine. But, I get access to vertex by it's name
. Example: I created 5 vertexes. Names are: 1, 2, 3, 4, 5. I deleted 3rd vertex. Names are: 1, 2, 4, 5 now. I added 1 vertex. Names are: 1, 2, 4, 5, 6 now. Now if I try to delete 4rd vertex, 5 vertex will be deleted, not 4 (because 5th vertex has index 4). If I try to delete 6th vertex, I will get error, because there are no 6th vertex in matrix.
It's sad, but I am working with framework, so I can't rewrite how to add vertexes. How can I change my code (look 'how I work with array of arrays code') so I can get access to vertexes by name in matrix? I need assoc array, but I don't know how to do it. Help please.
P.S.: delete code:
for (var i = 0; i < vertexCount; i++)
{
delete weightArray[i][target-1];
}
delete weightArray[target-1];
vertexCount = vertexCount - 1;
When I understand how to create/fill assoc array, I will have to rewrite part where I delete vertexes
Upvotes: 0
Views: 111
Reputation: 7269
This worked:
var weightArray = {};
// 1. Upgrade old rows and add 1 new column to each
for (row in weightArray)
{
weightArray[row][totalVertex+1] = 0;
}
// 2. Add new row
weightArray[totalVertex+1] = {};
// 3. Fill this row with zeros
for (row in weightArray)
{
weightArray[totalVertex+1][row] = 0;
}
All become fine, when I started to work with objects.
Upvotes: 0
Reputation: 42736
when you delete an array element, the index does not actually get deleted. So your decreasing the vertexCount is wrong as it will contain the wrong length as the length of the array will still be the same after a delete. You can avoid this by using splice
for(var i=0; i<weightArray.length; i++){
weightArray[i].splice(1,target-1);
}
weightArray.splice(1,target-1);
Also note that you do not need to keep track of the array length (ie vertexCount) you can just get the length of the array right from the array object.
EDIT
Then just do a delete and nothing else, no need for the loop or anything else.
delete matrix[vertexNumber]
As said earlier when you delete an element from an array the index doesnt actually get deleted
So using your example matrix with 3 vertices would look like:
[
[ 0, 0, 0], <-- vertex 0
[ 0, 0, 0], <-- vertex 1
[ 0, 0, 0] <-- vertex 2
]
and when you delete from array, say vertex 1, it will look like this
[
[ 0, 0, 0], <-- vertex 0
undefined, <-- old vertext 1, now equals undefined
[ 0, 0 ,0] <-- vertext 2
]
So your indexes are still the same, try the code below in like in the console to view
var matrix = [];
matrix[0] = [0,0,0];
matrix[1] = [0,0,0];
matrix[2] = [0,0,0];
console.log(matrix);
//[
// [ 0, 0, 0], <-- vertex 0
// [ 0, 0, 0], <-- vertex 1
// [ 0, 0, 0] <-- vertex 2
//]
console.log(matrix.length);
//3
Now if we delete vertex 1
delete matrix[1];
console.log(matrix);
//[
// [ 0, 0, 0], <-- vertex 0
// undefined, <-- vertex 1
// [ 0, 0, 0] <-- vertex 2
//]
console.log(matrix.length);
//3
Then add vertex 3
matrix[3] = [0,0,0];
console.log(matrix);
//[
// [ 0, 0, 0], <-- vertex 0
// undefined, <-- vertex 1
// [ 0, 0, 0], <-- vertex 2
// [ 0, 0, 0] <-- vertex 3
//]
console.log(matrix.length);
//4
Now delete vertex 3 and add vertex 4
delete matrix[3];
matrix[4] = [0,0,0];
console.log(matrix);
//[
// [ 0, 0, 0], <-- vertex 0
// undefined, <-- vertex 1
// [ 0, 0, 0], <-- vertex 2
// undefined, <-- vertex 3
// [ 0, 0, 0] <-- vertex 4
//]
console.log(matrix.length);
//5
as you can see the elements do not reposition themselves. So all you have to do is use
delete matrix[vertexNumber]
and that's it as the elements keep their index. So even when say you delete vertex 1, vertex 2 will still be at 2
Extra Edit
To keep the matrix square, this is where you would use vertexCount
. Keep track by decreasing it or increasing it as you add/remove vertex
Then when you need to add a row loop through and add the extra column if needed
for(var i=0; i<matrix.length; i++){
//if its one of the undefined indexes just continue
if(!matrix[i]) continue;
if(matrix[i].length < vertexCount){
var numExtraCols = vertexCount-matrix[i].length;
//Just a way to create an array with X number of slots
var extraCols = Array.apply(null,Array(extraCols)).map(Boolean).map(Number);
matrix[i].concat(extraCols);
}
}
And when you delete a vertex
for(var i=0; i<matrix.length; i++){
//if its one of the undefined indexes just continue
if(!matrix[i]) continue;
if(matrix[i].length > vertexCount){
var numExtraCols = vertexCount - matrix[i].length;
//remove X number of columns starting from the end.
matrix[i].splice(numExtraCols,matrix[i].length-1);
}
}
Note though since your array is keeping all the indexes its still going to have to iterate over it, which could have performance hit. Do not know if this would be a bigger performance hit then using an object or not. You will have to do tests.
to do with object, its mostly the same except you start matrix off as a object and not an array, and the looping is a bit different, but the size does change as when you delete a objects property the key is deleted with it
var matrix = {};
matrix[0] = [0,0,0];
matrix[1] = [0,0,0];
matrix[2] = [0,0,0];
to loop over it
var keys = Object.keys(matrix);
for(var i=0; i<keys.length; i++){
//use
matrix[ keys[i] ]
//in place of
matrix[i]
}
and deleting is the same
delete matrix[3]
Also since object does not have a native length you will have to do something like
var numVertexes = Object.keys(matrix).length;
Upvotes: 3