Implementation of Soundex() for Server Connect (node)

My background is very much in database management, starting back in the mid 1980s

Most of my early systems were Customer Relations Management, Medical Records, Human Resources Systems and Criminal Intelligence Analysis type systems.
In my early days of using DBase, Clipper, Foxpio, Visual Foxpro i make extensive use of the soundex() function to perform “fuzzy searches” on names.
I know i can implement this via custom queries as all forms of SQL support soundex but wanted the add to add this functionality to Wappler

For the few of those who may not know what soundex is, put simply it is a digital representation of a word based on its phonetic sound and was developed for use with names which can often sound alike but by spelt differently.
The function takes a word and returns the first letter followed by a number based on the phonetic sound of the word.
Basically it strips vowels and W, H,Y, removes double letters then resolves the remainder to number groups
The standard specified one letter followed by 3 numbers however it should be noted that the MySQL may actually return longer strings.

So to take a common English name “Smith”

This could be spelt as Smith, Smyth or Smythe
In a standard search they will appear different but with reference to their sounded equivalents they all resolve to S530

So here is my custom formatter for an English Language based implementation of Soundex()
I have added a Boolean optional “MySql Extended” option which extends the standard 4 digit representation to 5 digits where used with MySql and extended precision is required

The Function

// JavaScript Document
exports.soundex = function (name, extend) {

    return soundex(name, extend);
};

function soundex(name, extend) {
    let slen = extend ? 4 : 3;
    let s = [];
    let si = 1;
    let c;

    //              ABCDEFGHIJKLMNOPQRSTUVWXYZ
    let mappings = "01230120022455012623010202";

    s[0] = name[0].toUpperCase();

    for (let i = 1, l = name.length; i < l; i++) {
        c = (name[i].toUpperCase()).charCodeAt(0) - 65;

        if (c >= 0 && c <= 25) {
            if (mappings[c] != '0') {
                if (mappings[c] != s[si - 1]) {
                    s[si] = mappings[c];
                    si++;
                }

                if (si > slen) {
                    break;
                }
            }
        }
    }

    if (si <= slen) {
        while (si <= slen) {
            s[si] = '0';
            si++;
        }
    }

    return s.join("");
}

hjson

{
    type: 'method_soundex',
    groupTitle : 'Custom Formatters',
    groupIcon : 'fa fa-lg fa-key',
    addTitle: 'Soundex',
    title : 'Soundex',
    icon : 'fa fa-lg fa-font',
    state : 'opened',
    help : 'convert string into soundex code eqivalent',
    properties : [
    {
      group: 'Soundex Properties',
      variables: [
        { name: 'extend', optionName: 'extend', title: 'MySql Extended', 
          type: 'boolean', required: false, defaultValue: 'false'},

      ]
    }
  ]
  }

I plan to release difference() next which returns a numeric value from 0 - 4 based on the similarity of two Soundex representations (0 = no similarity, 4 = similar)

4 Likes

I had absolutely no idea soundex was a thing. Thanks Brian!

2 Likes

It’s actually a really old algorithm. 40 years plus

I first learned about it via a criminal intelligence system at work (written in COBOL !!!) in around 1984 but it was a standard function in a lot of early DBMS like dBase/ clipper/ MS Foxpro

1 Like

Cool! I started programming with Clipper Summer’87 and tried to use Soundex but there is several limitations for portuguese. Nowadays there is several ports to portuguese, maybe I’ll try again. In fact, I think most of people are using SQL wildcards to substitute the need for Soundex.

Thanks for sharing!