Quick one : Choose row from multiple columns?

Hiya, Really quick question: Is there a syntax to select a row in a table from multiple column values. Sort of like this -

choose row with a name of N and with a status of S in Table of StatusNameThings.

I know I can do it easily enough with a loop, but I just wondered whether I was missing a syntax trick. Have fiddled about with various combos of ‘with.’

Thanks in advance!

Ade.

Multi-column access for tables is not part of the Standard Library.

It is possible to write an I6 routine (and accompanying I7 phrase) to enable this, but the catch is that there’s some special magic going on during compilation to keep track of whether or not a row in a table has been chosen at any given point in the code. If the compiler deems that the code is trying to access a row when no row has been chosen, a problem message results during compilation, such as:

Problem. You wrote 'say "[name entry] is [readiness entry] in bay [bay entry]."'  : but no row seems to have been chosen at this point, so it doesn't make sense to talk about the entries within it...

The magic doesn’t recognize any added two-column version of the phrase as having chosen a row, so it’s necessary to first choose a row (using any method) to satisfy the compiler, then choose the row via the two-column method. Not great. (If anyone has any pointers on how to bypass this, I’d love to hear them. There doesn’t seem to even be any undocumented special template code to invoke to indicate a row has been chosen to the compiler – it just seems like something hardcoded as part of a validity check.)

EDIT: I belatedly realized that the ugliness of having to make a fake row choice can be wrapped up in the main phrase so that you don’t have to deal with it routinely as the author. The example has been modified accordingly.

EDIT 2: Oops. No, doing that doesn’t manage to fool the compiler; the row selection must occur within the same phrase as the entry access. I forgot to remove the fake row lookup in the when play begins rule during the too-hurried testing of the new approach.

Here’s a (poorly) working example:

"Two Column Access"

Place is a room.

Status is a kind of value. The statuses are ready and not ready.

Table of StatusNameData
name	readiness	bay
"Alice"	ready	2
"Bob"	not ready	1
"Carl"	ready	3

When play begins:
    choose row 1 in the Table of StatusNameData; [fakes out compiler]
    choose a row with a readiness of ready and a name of "Carl" in the Table of StatusNameData;
    say "[name entry] is [readiness entry] in bay [bay entry]."
    
Include
(-

! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
! Tables.i6t: Table Row Corresponding (two-column access)
! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====

[ TwoColTableRowCorr tab col1 lu_val1 col2 lu_val2    cola1 cola2 i j f1 f2 v vf1 vf2;

    if (col1 >= 100) col1=TableFindCol(tab, col1, true);
    if (col2 >= 100) col2=TableFindCol(tab, col2, true);

    if ((col1 == 0) || (col2 == 0)) rfalse;

    cola1 = tab-->col1;
    cola2 = tab-->col2;

    j = TableRows(tab);

    if (((tab-->col1)-->1) & TB_COLUMN_ALLOCATED) f1=1;
    if (((tab-->col2)-->1) & TB_COLUMN_ALLOCATED) f2=1;

    for (i=1:i<=j:i++) {
        vf1 = false; vf2 = false;
        if (f1) {
		        v = cola1-->(i+COL_HSIZE);
		        if ((~~((v == TABLE_NOVALUE) && (CheckTableEntryIsBlank(tab,col1,i)))) && (BlkValueCompare(v, lu_val1) == 0))
			        vf1 = true;
        } else {
	        if ((~~((lu_val1 == TABLE_NOVALUE) && (CheckTableEntryIsBlank(tab,col1,i)))) && (cola1-->(i+COL_HSIZE) == lu_val1))
			        vf1 = true;
        }
        if (f2) {
		        v = cola2-->(i+COL_HSIZE);
		        if ((~~((v == TABLE_NOVALUE) && (CheckTableEntryIsBlank(tab,col2,i)))) && (BlkValueCompare(v, lu_val2) == 0))
			        vf2 = true;
        } else {
		        if ((~~((lu_val2 == TABLE_NOVALUE) && (CheckTableEntryIsBlank(tab,col2,i)))) && (cola2-->(i+COL_HSIZE) == lu_val2))
			        vf2 = true;
        }
        if (vf1 && vf2) return i;
    }
    RunTimeProblem(RTP_TABLE_NOCORR, tab);
    return false;
];

-) after "Table Row Corresponding" in "Tables.i6t".

To choose a/the/-- row with a/-- (C1 - K valued table column) of (V1 - value of kind K) and a/-- (C2 - L valued table column) of (V2 - value of kind L) in (TN - table name):
    (- ct_0 = {TN}; ct_1 = TwoColTableRowCorr(ct_0, {C1}, {V1}, {C2}, {V2}); -).
2 Likes

Hold my beer.

When play begins:
    choose a row with a readiness of ready and a name of "Carl" in the Table of StatusNameData from the Table of StatusNameData;
    say "[name entry] is [readiness entry] in bay [bay entry]."

The stored row number is a number that varies.

To decide what K is the entry in a/an/the/-- col/column (C - a value of kind K valued table column): (- TableLookUpEntry({-my:ct_0}, {C}, {-my:ct_1}) -)

To decide what number is the current row number: (- {-my:ct_1} -)

To decide what number is the row number with (TC1 - K valued table column) of (w1 - value of kind K) and
  (TC2 - L valued table column) of (w2 - value of kind L) from/in (T - table name):
  repeat through T begin;
    unless w1 is the entry in col TC1, next;
    if w2 is the entry in col TC2, decide on the current row number;
  end repeat;
  decide on 0.

To look for the/a/-- row with (TC1 - K valued table column) of (w1 - value of kind K) and (TC2 - L valued table column) of (w2 - value of kind L) from/in (T - table name):
  now the stored row number is the row number with TC1 of w1 and TC2 of w2 in T;

To decide which number is with a/-- (TC1 - K valued table column) of (w1 - value of kind K) and
  a/-- (TC2 - L valued table column) of (w2 - value of kind L) in (T - table name):
  look for the row with TC1 of w1 and TC2 of w2 in T;
  decide on the stored row number;

Status is a kind of value. The statuses are ready and not ready.

Table of StatusNameData
name    readiness   bay
"Alice" ready   2
"Bob"   not ready   1
"Carl"  ready   3

It’s a horrible hack and I apologize to everyone. :grinning:

1 Like

Wow! Thanks for replies and the amazing coding! I shall experiment!!

I didn’t think there was this facility but thought it worth checking. What would be cool is if someone (a far better coder than I) was to develop a sort of ‘pseudo SQL’ extension for i7. The sysntax for table manipulation in i7 is pretty gnarly.

select all from the Table of Things where the status is 7 and the type is balloon

:slight_smile: Thanks again!

Ade.