Find diff between two ObjectScript lists

(Originally posted by @Eduard Lebedyuk on Intersystems CODE, 6/26/14) This code snippet determines the difference between two ObjectScript lists. The class method "test" runs the code, and its parameters are detailed in the comments:


Class eduardlebedyuk.diffLists Extends %RegisteredObject
{
    /// Finds diff between two lists.

    /// old - original list.

    /// new - modified list.

    /// .added - list with all added elements (present in new list, absent in old list.

    /// .deleted - list with all deleted elements (present in old list, absent in new list.

    classmethod test(old as %List, new as %List, output added as %List, output deleted as %List) as %Status [ Internal ]
    {
        set st=$$$OK
        if ($LISTVALID(old)=0) quit $$$ERROR($$$AttributeValueMustBeList,"old")
        if ($LISTVALID(new)=0) quit $$$ERROR($$$AttributeValueMustBeList,"new")
        try {
            for i=1:1:$LISTLENGTH(old)
            {
                set match=$LISTFIND(new,$LIST(old,i))
                if match'=0
                {
                    set $LIST(old,i)=""
                    set $LIST(new,match)=""
                }
            }
            set added=new
            set deleted=old
        } catch ex {
            set st=ex.AsStatus()
        }
        quit st
    }
}

Here's a link to the code on GitHub: https://github.com/intersystems-community/code-snippets/blob/master/src/...

Comments

If you want to compare collections, then you have to know what do you compare.
Let look on this examples:

1) Hobbies
   old: music, sport
   new: sport, music
   
   One could say, there is no difference (if all hobbies are equally preferred) 
   
2) Work instructions
   old: format_disk, create_backup
   new: create_backup, format_disk
   
   In this example, if the work is done in a wrong sequence, the data are lost.

In other words, if you compare collections, you have to take in account the
importance or unimportance of sequencies, which means, the compare function
needs a third input argument

compare(old, new, relyOnSequence, ...)

By the way, your test() method has his very special "point of view" of lists:

set old1=$lb("blue","red","green"),    new1=$lb("green","red","blue")
set null=$lb("", "", "")

do ##class(...).test(old, new, .add, .del) write add=nul, del=nul --> 11
do ##class(...).test(old, old, .add, .del) write add=nul, del=nul --> 11
do ##class(...).test(nul, nul, .add, .del) write add=nul, del=nul --> 11

Is this an expected behavior?