#2604 2D Array using List Issue and/or Bug

JohnNuccio Wed 10 May 2017

I am trying to create a 2D Array using List. The following code is a snippet of my attempt. But there appears to be a bug somewhere that causes the add of values to add to multiple Lists within the outer List and not just the one List specified.

Void main(){
   Str[] array := ["test","test2","test3"]
   List thing := [,]
   //Series Creator
   Obj[]? series := [,].fill([,],5)
   echo(series)
 for(i:=0;i<series.size;i++){
        echo()
 for(Int m:=0;m<array.size;m++){
    Str value := array[m]
    echo("Value to Add @ Iteration " + m + ": " + value)
    echo("Inner List @ Index " + i +": " + series[i])
    ((List)series[i]).add(value);
    echo("Full List after add: " +series)
 }
 }
 echo("Series Final: " +series)
}

Below is the console result of the first iteration through, which illustrates the problem. By the fifth iteration, all three values have been added 5 separate times to each individual List within the outer List.

[[,], [,], [,], [,], [,]]

Value to Add @ Iteration 0: test
Inner List @ Index 0: [,]
Full List after add: [[test], [test], [test], [test], [test]]
Value to Add @ Iteration 1: test2
Inner List @ Index 0: [test]
Full List after add: [[test, test2], [test, test2], [test, test2], [test, 
test2], [test, test2]]
Value to Add @ Iteration 2: test3
Inner List @ Index 0: [test, test2]
Full List after add: [[test, test2, test3], [test, test2, test3], [test, 
test2, test3], [test, test2, test3], [test, test2, test3]]...

brian Thu 11 May 2017

Based on your code that looks like the behavior you would expect. Although its a little awkward to understand. A 2D "list" is really just a list of lists. This snippet might be clearer:

list := [,]
for (r := 0; r<3; ++r)
{
  inner := [,]
  for (c := 0; c<3; ++c)
    inner.add("$r/$c")
  list.add(inner)
}
echo(list) 

fraya Fri 12 May 2017

I believe that the point is that:

Obj[]? series := [,].fill([,],5)

fills series 5 times with the same object list.

Hope this helps.

jhughes Fri 12 May 2017

@fraya I believe that is the problem, the same object being stored in multiple indices causes the duplicate write issue.

The core of this problem came up when attempting to solve something needing a 2D array and determining the fantom version of that. The only discussion that could be found on this topic was here http://fantom.org/forum/topic/1575 and doesn't really have a solid answer to the question of how to make 2D arrays without using loops.

Has there been any further work on this topic? Or is the solution still to make a single List and then make lists elsewhere (loop) and add them to the main list at the correct index? It would be nice to have a single line method to create a list of list objects without needing a loop to do so.

SlimerDude Mon 15 May 2017

As 2D arrays aren't used that much, I'd say a good suggestion (as per the topic you mention) would be to create your own wrapper classes.

Or, if you don't like double loops but are happy with nullable list values, you could use the size field to create the following (ugly) one-liner:

Obj?[]?[] list2d(Int x, Int y) {
    Obj?[]?[,] { it.size = y }.map { Obj?[,] { it.size = x } }
}


list := list2d(5, 5)
list[2][3] = "wotever"

Login or Signup to reply.