J. Doe J. Doe - 1 month ago 7
Javascript Question

How to find the best match for an object in an array?

If the following represents my array,

1 UserA | Bob Smith | 12345 | hello
2 UserA | Bob Smith | 12345 |
3 UserA | Bob Smith | 123 |
4 UserA | Bob Smith
5 UserB | Bob Smith | 12333 | hello


and I have the following object to compare with,:

UserA | Bob Smith | 2222


I'd like it to "best match" with the 4th row on my user array.

UserA | Bob Smith | 2222 | hello
also matches up with the 4th row.

What can I do to get the best match?

I can loop around and do a if-else but this seems very dirty hoping someone has a clever solution.




My current approach:

Try matching

UserA | Bob Smith | 2222 | hello


It returns nothing, so cut the last one and try again

UserA | Bob Smith | 2222


It returns nothing, so cut the last one and try again

UserA | Bob Smith


Matches 4th row, returns true! Thoughts??

Additional info:

[
{"Title": "UserA", "Name": "Bob Smith", "Number": 1234, "output": "hello"},
{"Title": "UserA", "Name": "Bob Smith", "Number": 1234},
{"Title": "UserA", "Name": "Bob Smith", "Number": 123},
{"Title": "UserA", "Name": "Bob Smith"},
{"Title": "UserA", "Name": "Bob Smith", "Number": 12333, "output": "hello"}
]


They all contain Title, Name, Number. Some may or may not contain additional info like "output"

Object I wanna match

{"Title": "UserA", "Name": "Bob Smith", "Number": 122, "output": "hello"}


will match with the 4th array object as it is matching left-to-right and that is the "best match"

Answer

Linear search:

<script>

function FindBestMatch( a, item )
{
    var bestIndex = null;
    var bestNumMatch = -1;
    var bestNumMismatch = 0;
    var numItemElements = item.length;
    for (var i in a)
    {
        for (var numMatch=0; numMatch<numItemElements; numMatch++)
        {
            if (a[i][numMatch]!=item[numMatch]) break;
        }
        var numMismatch = a[i].length - numMatch;
        if (numMatch==numItemElements && !numMismatch) return i;
        if (numMatch>bestNumMatch
          || (numMatch==bestNumMatch && numMismatch<bestNumMismatch))
        {
            bestIndex = i;
            bestNumMatch = numMatch;
            bestNumMismatch = numMismatch;
        }
    }
    return bestIndex;
}

var myArray = [
[ 'UserA', 'Bob Smith', 12345, 'hello' ],
[ 'UserA', 'Bob Smith', 12345 ],
[ 'UserA', 'Bob Smith', 123 ],
[ 'UserA', 'Bob Smith' ],
[ 'UserA', 'Bob Smith', 12345, 'hello' ]
];

var someItem = [ 'UserA', 'Bob Smith', 2222 ];

var i = FindBestMatch(myArray,someItem);

alert("The best match is number "+i+":\n\n"+myArray[i].join(" | "));

</script>