﻿ Comparing Two Lists/ Variables | InterSystems Developer Community |
Question
· Mar 22

# Comparing Two Lists/ Variables

Is there a way to compare the content of two variables/ lists and if they share a common element/ value return 1?

Example the two below both have "Yellow":

Set y = "Red, Green, Orange, Yellow"

Set x = "Purple, Black, Yellow, Pink"

The lists I am working with have over 30 elements/values that vary so it is difficult to hard code it to say look for "Yellow".

Product version: IRIS 2022.1
Discussion (12)3

If you want to treat them as lists, you probably want to use \$LISTFROMSTRING along with \$LISTGET, \$LISTFIND, and \$LISTLENGTH. All of which can be abbreviated to their initials, by the way - \$LFS, \$LG, \$LF, \$LL.

```set y = \$LFS("Red,Green,Orange,Yellow")
set x = \$LFS("Purple,Black,Yellow,Pink")
for i=1:1:\$LL(x){
if \$LF(y,\$LG(x,i)) > 0 {
write \$LG(x,i)_" found in both lists!",!
//Or whatever else you want to do when you find a match here . . .
}
}```

eventually better to check for longer lists

``````USER>s x=\$lfs("Purple,Black,Yellow,Pink")
USER>s y=\$lfs("Red,Green,Orange,Yellow")
USER>f z="y","x" f i=1:1:\$ll(@z) i \$i(dif(\$li(@z,i)))

USER>zw dif
dif("Black")=1
dif("Green")=1
dif("Orange")=1
dif("Pink")=1
dif("Purple")=1
dif("Red")=1
dif("Yellow")=2
``````

looping with \$o() over dif() allows programmatic check

This one will incorrectly flag an entry being in both lists if it appears twice in 1 list.    That may not be possible due to constrants elsewhere, but it's something to be careful about

``` Set x="Purple,Black,Yellow,Pink,Yellow,White,White,a,b,c,d,e,f"
Set y="Red,Green,Orange,Yellow,z,y,x,w,v"
Set Found=0
For i=1:1:\$Length(x,",") {
For i2=1:1:\$Length(y,",") {
If \$Piece(x,",",i)=\$Piece(y,",",i2) {
Write \$Piece(x,",",i)," = ",\$Piece(y,",",i2),!
Set Found=i_","_i2
Return Found
}
}
}```

@Herman Slagman this worked. However, when I had more than one repeating values e.g.

Set x="Purple,Black,Yellow,Pink,Orange,White,a,b,c,d,e,f"
Set y="Red,Green,Orange,Yellow,z,y,x,w,v"

It only returned that Yellow was found in both lists and ignored the Orange. I probably just need to edit the code that you shared. Thank you!

You can edit (or enhance) the above code to give you all matching elements. Below I share a code with you where you can choose the result data type (%List or %String) and the result scope (all the matching elements or just the first match).

``````/// Find common items of two lists or in two delimited strings
/// (as used in a \$piece-function)
///
/// itm1: first list (as %List or comma-delimited %String)
/// itm2: other list (as %List or comma-delimited %String)
/// ans : 0 = return a comma-delimited %String with the first match found
///       1 = return a comma-delimited %String with all matches found
///       2 = return a %List with the first match found
///       3 = return a %List with all matches found
///
/// return value: according to <ans> argument
///
/// Hint: the "\$d(var)," part is only needed if the <itm1> argument is
///       of %List type and can contain an "undefined" element like the
///       second element in \$lb(11,,33).
///
ClassMethod FindCommonItems(itm1, itm2, ans = 0)
{
set ptr=0, res="", all=ans#2
set:'\$lv(itm1) itm1=\$lfs(itm1) set:'\$lv(itm2) itm2=\$lfs(itm2)

while \$listnext(itm1,ptr,val) { if \$d(val),\$lf(itm2,val) { set res=res_\$lb(val) quit:'all } }
quit \$s(ans<2:\$lts(res), 1:res)
}
``````

You are right, but this was based on your original question: "if they share a common element/ value return 1"

But the code is easily enhanced to return all common values.

I haven't put a massive amount of thought into this so it might be garbage for time/space complexity....

``````Set y = "Red, Green, Orange, Yellow"
Set x = "Purple, Black, Yellow, Pink"
set x=\$ZSTRIP(x,"*W")
set y=\$ZSTRIP(y,"*W")
k ^||members
for i=1:1:\$L(x,","){
set ^||Members(\$P(x,",",i),1)=""
}

for j=1:1:\$L(y,","){
set ^||Members(\$P(y,",",j),2)=""
}

//Now do a quick traverse of our members
set key=""
set both=""
for   {
set key=\$O(^||Members(key))
quit:key=""
set key2=""
set key2=\$O(^||Members(key,key2))
if (\$O(^||Members(key,key2))'="" set both=both_key_","
}

w !,"These records are in both lists "_both``````