# searching more than one column in a table?

In this post capmikee sez:

Is this really possible? Section 16.5 of the docs implies that only a single column can be used to select a table row. Are there undocumented I7 ways to search on more? Or does this require magical I6 fu? TIA.

There’s no magic; as I understand it, you just have to use an I7 selector that’s clunkier than if you’re searching for one row. Something like:

[code]Table of products
index 1 index 2 result
3 4 12
6 7 42
1 1 1
5 3 15
3 6 18
2 3 6

To look up (first argument - number) and (second argument - number) in the table of products:
let result found be false;
repeat with N running from 1 to the number of rows in the table of products: [for some reason when I try to do this as a repeat through the table I get a Glulxe fatal error; maybe you can’t access chosen rows outside a broken repeat loop through a table]
choose row N in the Table of products;
if the index 1 entry is the first argument and the index 2 entry is the second argument:
now result found is true;
break; [having broken the repeat loop the chosen row row is the one we found]
if result found is true:
say the result entry;
otherwise:
say “No result found.”

When play begins:
look up 3 and 6 in the Table of Products;
say paragraph break;
look up 5 and 3 in the Table of Products;
say paragraph break;
look up 3 and 3 in the Table of Products;
say paragraph break.[/code]

As I recall, earlier when I complained about having to repeat through the table to do this, zarf said that anything else we might try would amount to repeating through the table anyway.

Yeah, searching a table is linear time no matter what.

By the way, about the comment about repeating through the table; in z-code (under 6L02), the code that has a repeat through the table:

[code]Lab is a room.

Table of products
index 1 index 2 result
3 4 12
6 7 42
1 1 1
5 3 15
3 6 18
2 3 6

To look up (first argument - number) and (second argument - number) in the table of products:
let result found be false;
repeat through the table of products:
if the index 1 entry is the first argument and the index 2 entry is the second argument:
now result found is true;
break; [having broken the repeat loop the chosen row row is the one we found]
if result found is true:
say the result entry;
otherwise:
say “No result found.”

When play begins:
look up 3 and 6 in the Table of Products;
say paragraph break;
look up 5 and 3 in the Table of Products;
say paragraph break;
look up 3 and 3 in the Table of Products;
say paragraph break.[/code]

yields a run-time problem as follows:

But under Glulx, as I mentioned in a comment in the original code, it’s a fatal error:

I’m guessing that this is not an Inform bug, as I shouldn’t be trying to access a chosen row after I’ve broken out of the repeat through the table loop, but is it a Glulxe bug that this is a fatal error rather than a run-time problem?

You’re correct that the chosen row is wiped once you leave the loop. (It’s reset to what it was before the loop started. This allows you to nest table loops.)

As for the fatal error, I think it’s a bug in the template code. Or rather, insufficiently defensive template code. It calls TableLookUpEntry() when the table argument is zero, and the first thing it does is read address zero. The word at address zero in a Z-code game is usually \$500 or \$800 (because the version byte is 5 or 8), but the word at address zero in a Glulx game is always \$476C756C. That leads to a quick memory over-run.

TableLookUpEntry() should catch this case, I’d say.

Or, ideally, the compiler should be smart enough to notice that you’re printing a table entry when no row is selected.

I threw in a bug report: inform7.com/mantis/view.php?id=1360