CK1
CK1

Reputation: 542

Is there any kind of matrix filter in TCL?

Given the following matrix:

1 2 3 4
1 2 3 0
1 2 0 0
1 0 0 0
1 0 0 5

Return the rows that contain searched information.

For Example:

matrixname filter {{1} {} {3} {}}

The return would be:

1 2 3 4
1 2 3 0

and

matrixname filter {{1} {} {} {4}}

The return would be:

1 2 3 4

Does something like this already exist? I am thinking almost SQL-esk type of function WHERE COL = VALUE AND ORDER BY type of thing.

I have looked around and I am not finding anything.

---------------------------------EDIT

I have come up with the following to search the given fields.

::struct::list dbJoin -inner\
                      -keys FoundKeyList\
                      1 [::struct::list dbJoin -inner\
                                               1 [MatrixName search -nocase column 2 $ITEM1]\
                                               1 [MatrixName search -nocase column 1 $ITEM2]]\
                      1 [MatrixName search -nocase column 0 $ITEM3];

This will provide a list of row numbers that match the search criteria. then you can just use MatrixName get row row or matrixName get rect column_tl row_tl column_br row_br to get the results.

Anyone have any feedback on this?

Upvotes: 0

Views: 366

Answers (2)

syox
syox

Reputation: 3

package require struct::matrix 

struct::matrix xdata
xdata add columns 4
xdata add rows    5

xdata set rect 0 0 {
{1 2 3 4}
{1 2 3 0}
{1 2 0 0}
{1 0 0 0}
{1 0 0 5}
}

foreach {c r} [join [xdata search -regexp all {1*3}]] { puts [xdata get row $r] }
# 1 2 3 4
# 1 2 3 0

foreach {c r} [join [xdata search -regexp all {1*4}]] { puts [xdata get row $r] }
# 1 2 3 4

xdata destroy

This should achieve the expected results.

Upvotes: 0

andy mango
andy mango

Reputation: 1551

Two options come to mind.

In tcllib, there is the struct::matrix package. It has a search command. However, that command searches for patterns on individual cells (which can be constrained to particular columns) and you would need to write a procedure to perform the multiple searches required to achieve the conjunctive match you describe.

The other option is TclRAL. This will give you a relation value (aka a table) and you can perform a restrict command to obtain the subset matching an arbitrary expression, e.g.

set m [ral::relation table {C1 int C2 int C3 int C4 int}\
    {1 2 3 4} {1 2 3 0} {1 2 0 0} {1 0 0 0} {1 0 0 5}]
set filt [ral::relation restrictwith $m {$C1 == 1 && $C3 == 3}]

However, both of these options are somewhat "heavyweight" and might be justified if there are more operations you need to perform on your tabular data than you indicate in your question. If the scope of your problem is as small as your questions indicates, then simply dashing off a procedure, as the other commenters have suggested, may be your best bet.

Upvotes: 1

Related Questions