Reputation: 1295
In old Lasso 8 code, I would frequently use field('foo', -recordindex=(loop_count - 1))
in a conditional to display a header row in a table when a value changed between records.
In Lasso 9, the -recordindex
parameter seems to be ignored. It's also not documented.
My first workaround would be to set a variable with each record iteration and compare the current record's field against that value.
<?= var('lastSortFieldValue') = null ?>
[records]
[if(field('sortField') != $lastSortFieldValue)]
<!-- display header -->
[/if]
<!-- display row -->
<?= $lastSortFieldValue = field('sortField') =>
[/records]
Any recommendations for a best practice here?
Upvotes: 0
Views: 86
Reputation: 133
However elegant Brads custom method is I would advice against using it. It is slower than setting and comparing a local variable.
local(
timer,
loops = 1000,
present_value,
prev_value,
out = string,
result = string
)
inline(-database = 'mysql', -sql = "SELECT * FROM help_category") => {
#timer = micros
loop(#loops) => {
rows => {
#present_value = field('name')
#prev_value != #present_value ? #out -> append('<hr />Here be a new field<br />')
#out -> append(#present_value + '<br />')
#prev_value = #present_value
}
}
#result -> append('Result using local ' + ((micros - #timer) / # loops) + '<br />')
#timer = micros
loop(#loops) => {
rows => {
#present_value = field('name')
loop_count > 1 and #prev_value != fieldFromRow(#present_value, loop_count -1) ? #out -> append('<hr />Here be a new field<br />')
#out -> append(#present_value + '<br />')
}
}
#result -> append('Result using fieldFromRow ' + ((micros - #timer) / # loops) + '<br />')
}
#result
-> Result using local 637
Result using fieldFromRow 1612
Upvotes: 1
Reputation: 308
Your workaround of setting the variable is probably the best thing to do. (Though I would make it a local variable instead of a thread variable as it probably doesn't need to have thread scope.)
If you really wanted a method that would do what field(..., -recordIndex) used to do, then here's a method to do that:
define fieldFromRow(field::string, row::integer) => {
local(curMap = inline_scopeGet)
!#curMap || #curMap->size == 0? return null;
local(stashRow) = #curMap->find(::currentrow)
handle => {
#curMap->insert(::currentrow = #stashRow)
}
#curMap->insert(::currentrow = #curMap->find(::currentset)->get(INLINE_RESULTROWS_POS)->get(#row))
return column(#field)
}
This method gets the current inline information. Then it stashes the current row and sets a handler to restore the current row when all is said and done. It then sets the current row to the one specified in the method call and returns the value for the specified field. A bit of a hack, but it works in my basic testing.
Upvotes: 1