(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/...
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?