0155

Müller Equals Muller

text
unicode
search

Müller Equals Muller

A support agent types muller into the customer search and finds nothing — the customer is stored as Müller GmbH. Business Central compares what was typed against what is stored, and ü is simply not u; AL ships no diacritics-folding API, so a search that shrugs off accents, case and punctuation needs its own normalizer. You are building it.

Requirements

Create a codeunit named "Search Key Folding" with two public procedures:

procedure ToSearchKey(Input: Text): Text
procedure CountCustomersMatching(Query: Text): Integer

Pick object IDs in the 50100–50199 range, and reference other objects by name, never by ID.

ToSearchKey

Turns arbitrary text into a canonical search key. Every character of Input falls into exactly one of three classes:

  • Plain letters a–z / A–Z and digits 0–9 are kept.
  • A character in the fold map below is replaced by its mapped letters.
  • Every other character — spaces, punctuation, dashes, symbols, and any character not covered above — is a separator.

The fold map (lowercase and uppercase fold the same):

Characters Fold to
à á â ã ä å A
è é ê ë E
ì í î ï I
ò ó ô õ ö ø O
ù ú û ü U
ý ÿ Y
ñ N
ç C
ß SS
æ AE
œ OE

Rules for the returned key:

  1. Kept and mapped letters appear uppercased; digits appear unchanged.
  2. A run of one or more separators between kept characters becomes exactly one space; separators at the start or end of the input are dropped entirely.
  3. If nothing survives — the input is empty or consists only of separators — the key is the empty string.
  4. A key is a fixed point: ToSearchKey(ToSearchKey(X)) equals ToSearchKey(X) for any input.

Examples: ToSearchKey('Müller GmbH') = MULLER GMBH; ToSearchKey('O''Brien & Sons, Ltd.') = O BRIEN SONS LTD; ToSearchKey('Straße 4711') = STRASSE 4711; ToSearchKey(' --Nordwind-- ') = NORDWIND.

CountCustomersMatching

  1. Returns how many Customer records have a Name whose search key equals the search key of Query.
  2. A Query whose search key is empty matches nothing and returns 0 — an empty key must never sweep up records.
  3. The procedure never raises an error, whatever Query contains; a search that finds nothing returns 0.

What the tests check

The grading tests call ToSearchKey and compare the returned key character for character: the fold map applied to German, Nordic, French and Spanish names, every character of the fold map in both its lowercase and uppercase form, ß doubling to SS, the æ/œ ligatures, digits kept, punctuation runs collapsing to single spaces, trimmed ends, the empty and all-punctuation inputs yielding the empty string, and re-folding a key returning it unchanged. Several expected keys are built around randomly generated text, so hardcoding the examples will not pass — and plain UpperCase fails every accented case, because Ü is still not U. The lookup tests seed customers such as TRYAL-SKF1 Müller GmbH and TRYAL-SKF1 MULLER GMBH next to decoys like TRYAL-SKF1 Mueller GmbH, then assert exact counts for hits, misses, a separator-only query, and the empty query. The tests run in a real company where other customers exist — the seeded names carry unique markers, and your counts must be driven purely by the key equality described above.

Learn More

Hint 1
UpperCase gets you a third of the way at best: it turns ü into Ü, never into U. Nothing in AL folds accents for you — every mapped character has to be translated by your own code, and every unmapped one is either kept or a separator.
Hint 2
Classify one character at a time into three buckets: a fold-map hit becomes its replacement, a plain letter or digit becomes itself uppercased, everything else is a separator. Emit a space only when a separator run sits between two kept characters — collapsing and trimming then fall out for free.
Hint 3
Text[i] hands you a Char, and a Char compares against literals like 'ä' in a case statement or a set. For the lookup, no database filter can see your folded key — fold the query once (empty key: exit 0 immediately), then walk the Customer records counting those where ToSearchKey(Name) equals it.
ALBusiness Central 28.5
Press Compile to check your code compiles — Submit runs the tests.
The code editor is desktop-only
Open this problem on a computer to write and run code. Reading the description, tests and discussion works fine here.