|
High-speed Lookups with Clusters: FINDROW(), FINDVALUE(), and FINDVALUE$() |
Clusters provide a powerful way to create high-speed lookup tables,
ideal for tasks such as translation. Each field within a cluster can
serve as a searchable key, and lookups are performed using the
findrow() function.
findrow() supports all data types, allows duplicate keys,
and permits key values to change over time. Missing or unset values are
handled naturally using empty strings or zero—without special
cases, performance penalties, or data loss from duplicate empty keys.
findrow() is a highly optimized function that uses hashing
to perform lookups in O(1) constant time, enabling over
10 million searches per second on a modern PC, regardless of the
number of rows, subject to available RAM. This makes findrow() ideal for workloads
requiring fast, deterministic data access.
Given a cluster name, a cluster field to search, and a value to match,
findrow() returns the first row where the key is found and
makes that row current, or returns 0 if the key is not
found.
To handle duplicate keys, findrow() supports an optional
parameter that selects the Nth occurrence of a matching key.
TRUE if
you want a case-sensitive search.Program Explanation:
1. Cluster Definition:
A cluster named trans is defined to store English words and their corresponding German translations. The cluster has two fields: english$ for English words and german$ for German words.
2. Adding Data:
The program adds entries to the trans cluster:
'apple' is paired with the German word 'der Apfel'.'banana' is paired with the German word 'die Banane'.3. User Input Assignment:
The variable word$ is assigned the value of a$, which is assumed to be a word entered by the user that they want to translate.
4. Searching for English Word:
The program searches the trans cluster for a row where the english$ field matches word$ (the word entered by the user). The row number is stored in the variable row.
5. English to German Translation:
If the word is found (row > 0), the program prints the English word followed by its German translation, using ' >> ' as the separator. The loop then exits since the translation has been found.
6. Searching for German Word:
If the word wasn't found in the English field, the program then searches the trans cluster for a row where the german$ field matches word$.
7. German to English Translation:
If the word is found in the German field (row > 0), the program prints the German word followed by its English translation, again using ' >> ' as the separator. The loop then exits since the translation has been found.
8. No Translation Found:
If the word is not found in either the English or German fields, the program prints a message indicating that there is no translation available for the word entered by the user.
The findvalue() and findvalue$() functions
look up a row in a cluster by searching one field, then return a
specified value when that row is found.
The returned value may come from the matched row, such as
emp->name$ or emp->salary, or it may be any
compatible expression, variable, or constant.
As a side effect, _integer is set to the matching row
number. If no matching row is found, _integer is set to
0.
The current cluster row is not changed by findvalue() or
findvalue$(). This means they can be safely used inside
cluster iteration loops without disturbing the loop's current row.
Problem: Business programs often need to find a row by one
field, then read another field from that same row. Without a helper
function, this requires a findrow(), a test for zero,
and a separate field reference.
Solution: findvalue() and
findvalue$() combine the lookup, the not-found test,
and the returned value into one expression.
Efficiency: The function uses Sheerpower's cluster lookup model directly. Any cluster field can become a key when searched, so no separate key/value table or declaration is needed.
Takeaway: Use findvalue() or
findvalue$() when the real intent is: find this row,
return this value, otherwise use this explicit fallback.
findvalue() searches a cluster field for a matching
value. If a matching row is found, Sheerpower positions the cluster
to that row, evaluates found_result, and returns the
resulting numeric value.
If no matching row is found, findvalue() returns
not_found_result.
Use findvalue() when the value being returned is numeric.
search_field
A cluster field designator that identifies the field to search. This
is the same form accepted by findrow(), such as
emp->id, emp->salary, or
invoice->number.
search_value
The value to match in search_field. The search value may
be numeric or string, depending on the field being searched.
found_result
The numeric value to return when a matching row is found. This may be
a numeric field designator, a numeric variable, or a numeric constant.
If found_result is a cluster field designator, it is
evaluated after the cluster has been positioned to the matched row.
not_found_result
The numeric value to return when no matching row is found.
This argument is required. There is no silent default.
nth
Optional. Selects which matching row to use when duplicate matches
exist. 1 means the first match and is the default.
case_sensitive
Optional. Controls whether string searches are case-sensitive. When
this argument is used, the nth argument must also be
supplied.
findvalue() returns a numeric REAL value.
Both found_result and not_found_result must
be numeric.
findvalue$() searches a cluster field for a matching
value. If a matching row is found, Sheerpower positions the cluster
to that row, evaluates found_result, and returns the
resulting string value.
If no matching row is found, findvalue$() returns
not_found_result.
Use findvalue$() when the value being returned is a
string.
search_field
A cluster field designator that identifies the field to search. This
may be a string field, such as emp->name$, or a numeric
field, such as emp->id.
search_value
The value to match in search_field. The search value is
not determined by the $ on findvalue$().
The $ controls the return type, not the search type.
found_result
The string value to return when a matching row is found. This may be
a string field designator, a string variable, or a string constant.
If found_result is a cluster field designator, it is
evaluated after the cluster has been positioned to the matched row.
not_found_result
The string value to return when no matching row is found.
This argument is required. There is no silent default.
nth
Optional. Selects which matching row to use when duplicate matches
exist. 1 means the first match and is the default.
case_sensitive
Optional. Controls whether string searches are case-sensitive. When
this argument is used, the nth argument must also be
supplied.
findvalue$() returns a string value. Both
found_result and not_found_result must be
strings.
The most important rule is that found_result is evaluated
at the matched row.
Sheerpower finds the matching row, positions the cluster to that row, evaluates
found_result, and then restores the original row position. After the
call, the cluster's current row is exactly what it was before the call; only
_integer reflects the matched row number.
This returns Bob's salary, not the salary from the row that happened to be current before the call.
This is what makes findvalue() more than a simple
existence test. It is a lookup-and-return operation.
The not_found_result argument is required for both
findvalue() and findvalue$().
This forces every call site to make the not-found behavior visible. There is no hidden default and no silent assumption.
0 or "" when absence and empty mean
the same thing.
A traditional lookup with findrow() looks like this:
With findvalue(), the same intent becomes one
expression:
The shorter form is not just more compact. It removes the row-number bookkeeping and says directly what the program means.
Problem: Repeated findrow() code makes the
developer write mechanical lookup steps instead of the business
intent.
Solution: findvalue() and
findvalue$() express the lookup and returned value in
one readable expression.
Efficiency: Because Sheerpower clusters can search on any field, this works without extra lookup tables, declarations, or special key/value conventions.
Takeaway: When you want data from the matched row, use
findvalue() or findvalue$() instead of
manually finding the row and testing it.
findvalue() returns a numeric value from a matched row.
findvalue$() returns a string value from a matched row.
The search field may be numeric or string. The $ suffix
on findvalue$() describes the returned value, not the
searched value.
The found result is evaluated after the matching row is found and the cluster is positioned to that row.
The not-found result is required, so every lookup clearly states what happens when the row is absent.
(Show/Hide Sheerpower FINDVALUE() Takeaways)findvalue() returns a numeric value from a matched
row.
findvalue$() returns a string value from a matched
row.
$ suffix controls the return type, not the
search type.
nth argument selects which duplicate
match to use.
case_sensitive argument controls whether
string matching is case-sensitive.
findrow() is a core language feature for fast,
deterministic data access, not a helper routine or external index.
findrow() removes an entire class of application-level
indexing code while remaining simple to read and reason about.
|
Hide Description
|
|
|
Enter or modify the code below, and then click on RUN |
|
Looking for the full power of Sheerpower?
Check out the Sheerpower website. Free to download. Free to use. |