From: Bezoar on
On Jul 18, 2:01 pm, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote:
> On Jul 18, 3:51 am, yilmaz <yyyyil...(a)gmail.com> wrote:
>
>
>
> > Thank you for your reply and the pointers, Bezoar! They help a great
> > deal.
>
> > Besides the printing of column headings and rows, I was also looking
> > for a way to extract the values given the key. Like if I have
> > extracted FruitA,category1,type1,name1  from the list , then I would
> > go and map the FruitA, category1, type1, and name1 to form the right
> > index in the original array to grab the value for that key.
>
> > So, for example, if I have FruitA,category1,type1,name1 key from the
> > list, then there will be a mapping method that would set the
> > dimensions like:
>
> > set columns {
> > {fruit 0}
> > {category 1}
> > {type 2}
>
> > }
>
> > set rows {
> > {name 4}
>
> > }
>
> > Then, the key FruitA,category1,type1,name1 would be set through these
> > methods to give the real positions of items in the original array.
>
> > If the given key after mapping is found in the array, then its value
> > is extracted and put into the table cell. At that time, all column
> > headings and row headings will already be printed into XML. Only the
> > values like 0.1345 will be printed at the end when the table headings
> > are in place.
>
> > --0-------1----------2-------3----4--------------
> > FruitA,category1,type1,name1  0.1345
>
> > Maybe I am doing too many checks, but that way I guess I will have the
> > correct values printed into the table cells. That's why I was thinking
> > about a recursion through a tree to get the key bindings from the
> > list .
>
> > Thank you for your help. If you can just comment if I am on the right
> > track with this implementation, I'd be very grateful.
>
> > On Jul 18, 1:04 pm, Bezoar <cwjo...(a)gmail.com> wrote:
>
> > > On Jul 18, 2:08 am, yilmaz <yyyyil...(a)gmail.com> wrote:
>
> > > > Hi all,
>
> > > > I would appreciate any help.
>
> > > > I have a multi-dimensional array representing the column and row
> > > > dimensions in a table and values in the table cells:
>
> > > > --0---------1-------------2-------3-----------4--------------
> > > > FruitA,category1,type1,name1  0.1345
> > > > FruitA,category1,type2,name1  0.1123
> > > > FruitA,category2,type1,name1  0.1993
> > > > ..............................
> > > > FruitA,category2,type2,name2  0.1183
> > > > ...............................
> > > > FruitA,category3,type1,name2  0.1100
> > > > ........
> > > > FruitB,category1,type1,name1  0.0100
> > > > FruitB,category1,type2,name1  0.1123
> > > > .......
> > > > FruitC,category1,type1,name1  0.1403
> > > > .........................
>
> > > > In the array above, FruitA,category1,type1 represents the column
> > > > dimensions in the table, name1 represents a row dimension, and the
> > > > 0.1345 represents a value in the given cell in the table.
>
> > > > I need to transfer the array dimensions above into a hierarchical flat
> > > > list to first configure my column and row headings and sort them
> > > > alphabetically before dumping these into an XML-like tree.
>
> > > > My list will be constructed such as to have one-to-one correspondence
> > > > between the related dimensions like this:
>
> > > > set columnHeadingsList {
> > > > {FruitA FruitA ... FruitB FruitB ... FruitC ...}   # sorted
> > > > alphabetically
> > > > {{category1 category2 ....} {category1  category2 ...} }   #sorted
> > > > alphabetically
> > > > {{type1  type2 ...} {type1  type2 ...} {type1 type2 ...} {type1
> > > > type2 ...}}  # sorted alphabetically
>
> > > > }
>
> > > > set rowHeadingsList {
> > > > {name1  name2 ....}  # sorted alphabetically
>
> > > > }
>
> > > > I have the methods to extract the dimensions to form the lists and can
> > > > do the sort alphabetically.
>
> > > > My concern is the following, though. When I set up the column headings
> > > > and row headings in these list,  I will have to implement some
> > > > recursive tree traversal method that will remember the path to the
> > > > parent nodes to eventually extract the whole path with dimensions.
>
> > > > For example, when I give the row and column index , it should return
> > > > FruitA,category1,type1,name1 and then using some mapping method I can
> > > > verify if the entry with such index exists inthe originalarray and
> > > > if it exists the value 0.1345  for the key
> > > > FruitA,category1,type1,name1 should be extracted and put into the
> > > > corresponding XMLtag.
>
> > > > I looked at the tree traversal methods but found nothing that
> > > > satisfies my requirements. Has someone maybe more experience in table
> > > > list traversal methods that would suit my case ? I'd appreciate any
> > > > help with this.
>
> > > > Thank you.
> > > > YY.
>
> > > If I understand you correctly you have an array with your key being
> > > the column/row as index and the value being some number. From the
> > > array you have extracted the columns  and row indexes and have
> > > alphabetized them. Now you want to regurgitate the array in xml but do
> > > it alphabetically by index.  Your method would seem to require
> > > foreach fruit [lindex $ColumnHeadingList 0 ] {
> > >    foreach category [lindex $ColumnHeadingList 1 ] {
> > >         foreach type [lindex $ColumnHeadingList 2 ] {
> > >                  foreach  row $rowHeadingsList {
> > >                      if { [ info exists dataArray($fruit,$category,
> > > $type,$row) ] } {
> > >                            outputToXML "$fruit,$category,$type,$row"
> > > \ $dataArray($fruit,$category,$type,$row)
> > >                      }
> > >                   }
> > >           }
>
> > > }
>
> > > However it may be easier to pad the numbers of the columns and use the
> > > dictionary sort
> > > so convert your column1 to column00001 and type1 to type00001 etch for
> > > all column types and
> > > rows.  This way if your number portion exceeds 9  then 00001 - 00009
> > > will sort before 00010 and higher.  Then to quickly sort all your data
> > > and output would be this.
>
> > > foreach idx [ lsort -dictionary [array names dataArray ] ]  {
> > >     outputToXML  [removePadding $idx ] $dataArray($idx)
>
> > > }
>
> > > Bezoar
>
> > > Note: I just typed these in so minor syntax errors may have crept in
>
> It is hard to figure out what hierarchy you are trying to get at. What
> does one XML record look like?
>
> However, I have two suggestions for modeling multi-dimensional arrays
> with Tcl arrays:
>
> 1: Use a formal Tcl list as the key:
>
> set md_array([list $fruit $cat $name]) $value
>
> 2. Sort by using multiple use of [lsort]:
>
> set keys [array names md_array]
>
> set sorted_keys_2_1_0 [lsort -index 0 [lsort -index 1 [lsort -index 2
> $keys]]]
>
> Look at the [lsort] manpages to see if additional options would help
> you out.
>
> The reason to use a Tcl list as a key is to make sure quoting is done
> properly and to aid in sorting based upon the list elements.

Ok so it sounds like you do not want to use the
FruitA,category1,type1,name1,row as your key but convert the key to
0,1,1,1,1 . You explanation is confusing since Tcl uses strings for
indexs into arrays so "FruitA,category1,..." is just as good as
0,1,1,1,1 a conversion is just not necessary. So to get the value
you would have something like:

# fill your data array I assume its global but you can modify procs to
pass it in

set dataArray(0,1,1,1,1) .1345
.....

# example proc for Converting FruitA to 0 FruitB to 1 etc
proc FruitToNum { fruit } {
scan [string range $fruit [string length "Fruit" ] end ] %c idx
set idx [expr $idx - 65 ]
return $idx
}
# convert 0 to FruitA 1 to FruitB etc
proc NumToFruit { num } {
return "Fruit[format %c [expr $num + 65] ]"
}
#other NumToCategory etc
#other Category,type,row to Num procs
....

proc getNumIdx { fruit cat type name row } {
set fidx [FruitToNum $fruit ]
set cidx [CategoryToNum $cat]
set tidx [TypeToNum $type]
set nidx [NameToNum $name ]
set row [RowToNum $row ]
return "$fidx,$cidx,$tidx,$nidx,$row"
}
# reverse convert 0,1,1,1,1 to FruitA,Category1,etc
proc getTextIdx { fidx cidx tidx nidx ridx } {
set fruit [NumToFruit $fidx]
...
}

# if not found will return default of -1 unless another value
specified by caller.
proc getValue {fruit cat type name row {ValueDefault -1 } } {
global dataArray
set idx [getNumIdx $fruit $cat $type $name $row ]
if { [info exists dataArray($idx) ] } {
return $dataArray($idx)
}
return $ValueDefault
}
# set the value in the dataArray using Textual indexes
proc setValue { fruit cat type name row value } {
# implement similar to above
}

# getValue does all work converts textual indexs to number index and
returns value
set value [getValue FruitA category1 type1 name1 row ]