Search an object in a ListOfObj

Primary tabs

This is the translation of the original question.
ObjectScript, Caché

Hi all.

I have a reponse message that has a property of the type %Collection.ListOfObj and I need to search for an item in this list. Let me show you.The Response message has a collection of type LabCenter

Class ListLabCenter Extends Ens.Response
{

Property ListCenter As list Of LabCenter;  
Storage Default
{
<Data name="ListLabCenterDefaultData">
<Subscript>"ListLabCenter"</Subscript>
<Value name="1">
<Value>ListCenter</Value>
</Value>
</Data>
<DefaultData>ListLabCenterDefaultData</DefaultData>
<Type>%Library.CacheStorage</Type>
}  
}

 

Class LabCenter Extends (%SerialObject%XML.Adaptor)
{

Property LabId As %String;  
Property Center As %String;  
Property Code As %String;  
Storage Default
{
<Data name="LabCenter">
<Value name="1">
<Value>LabId</Value>
</Value>
<Value name="2">
<Value>Center</Value>
</Value>
<Value name="3">
<Value>Code</Value>
</Value>
</Data>
<State>LabCenterState</State>
<StreamLocation>^DKV.LaboCe4177.LabCenterC486S</StreamLocation>
<Type>%Library.CacheSerialState</Type>
}  
}
 

I retrieve the message that I want to evaluate

> set obj=##class(ListLabCenter).%OpenId(1)
> zw obj                                                                            
obj=<OBJECT REFERENCE>[2@ListLabCenter]
+----------------- general information ---------------
|      oref value: 2
|      class name: ListLabCenter
|           %%OID: $lb("1","ListLabCenter")
| reference count: 2
+----------------- attribute values ------------------
|       %Concurrency = 1  <Set>
+----------------- swizzled references ---------------
|      i%ListCenter = ""
|   i%ListCenter(1) = $lb($lb("A08829848","A088298480001",""))
|   i%ListCenter(2) = $lb($lb("A08829848","A088298480002",""))
|   i%ListCenter(3) = $lb($lb("A08829848","A088298480003",""))
|   i%ListCenter(4) = $lb($lb("U66700196","U667001960002",""))
|   i%ListCenter(5) = $lb($lb("U66700196","U667001960003",""))
|      r%ListCenter = "1@%Collection.ListOfObj"
|   r%ListCenter(1) = "3@LabCenter"
+-----------------------------------------------------

I have to locate a specific object, so I create an object with the data I want to find

 > set objFind = ##class(LabCenter).%New()
 > set objFind.LabId="A08829848"
 > set objFind.Center="A088298480003"
 > zw objFind
objFind=<OBJECT REFERENCE>[5@LabCenter]
+----------------- general information ---------------
|      oref value: 5
|      class name: LabCenter
| reference count: 2
+----------------- attribute values ------------------
|             Center = "A088298480003"
|               Code = ""
|              LabId = "A08829848"
+-----------------------------------------------------
 

I have tried to do the search using the command $LISTFIND but the object is not of type list

> w $Listvalid(obj.ListCenter)
0

Then I thought about using the command Find de %Collection.ListOfObj but I get an error if I try to find the object

How could I locate the item I am looking for in this collection? I want to avoid using a loop and checking the elements one by one because I don't know how many items I'll have.

Regards,
Francisco López

UPDATE

This is the real scenario.

There is a laboratory that has several centers where blood tests are performed. But the laboratory also belongs to a group of laboratories that are identified with another laboratory code

Example:
Kurro Laboratory - ID: A000001
Centers:

  • KC01
  • KC02
  • KC03

Evgeny Laboratory - ID: A000002
Centers:

  • EC01
  • EC02
  • EC03

Malaga laboratory group - ID: A000003
Centers:

  • 01KC01
  • 01KC02
  • 02EC01
  • 02EC03

When a blood test is performed, the laboratories send the information on which insured person has been tested. This information is stored in a database that is updated daily.
The next day, a process recovers all the records from the previous day and that is when I have to retrieve ONLY those from the Kurro laboratory or those associated with the Malaga Laboratorio group.

To find out which laboratory and center identifier the Kurro laboratory belongs to, I have a table that identifies it. My ESB process retrieves it and that is where I have the data (ListLabCenter)

  • (A000001 - KC01)
  • (A000001 - KC02)
  • (A000001 - KC03)
  • (A000003 - 01KC01)
  • (A000003 - 02KC01)

As I have to evaluate ALL the records of the previous day (one by one), so I was looking for a way to find the insured's information quickly, filtering only by those of the Kurro laboratory.

Is my problem clearer now?

Replies

Create a FindLab() method in your ListLabCenter class, something like:

Method FindLab(start = 0, LabId = "", Center = "", Code = "")

{    set nc1=LabId="", nc2=Center="", nc3=Code=""

     for i=start+1:1:..Labs.Count() {

         set tmp=..Labs.GetAt(i)

         if tmp.LabId=LabId!nc1, tmp.Center=Center!nc2, tmp.Code=Code!nc3 return i

}

   quit 0

}

Then use it as follows:

write obj.FindLab(0,"A08829848","A088298480003","") to find a specific Lab

or 

set  center=0
for  { set center = obj.FindLab(center,,"A088298480003")
       quit:'center
       /* do something with center *./
}

to find all LabCenter objects where Center = "A088298480003"

Thanks for your code.

I'm afraid that I'll use a loop to search my lab-center instead of find using a ENSLib function.

I've updated my question to clarify what is the real scenario.

Best regards,
Francisco López

Finally, I've added the following method in request class

 
Method Find(item As LabCenter)
{
    for i=1:1:..ListCenter.Count(){
        set tmp=..ListCenter.GetAt(i)
        if tmp.LabId=item.LabIdtmp.Center=item.Centertmp.Code=item.Code return i
    }
 
    quit 0
}

By this way, I find my Lab-Center

> set obj=##class(ListLabCenter).%OpenId(1)
> zw obj
obj=<OBJECT REFERENCE>[2@ListLabCenter]
+----------------- general information ---------------
|      oref value: 2
|      class name: ListLabCenter
|           %%OID: $lb("1","ListLabCenter")
| reference count: 2
+----------------- attribute values ------------------
|       %Concurrency = 1  <Set>
+----------------- swizzled references ---------------
|      i%ListCenter = ""
|   i%ListCenter(1) = $lb($lb("A08829848","A088298480001",""))
|   i%ListCenter(2) = $lb($lb("A08829848","A088298480002",""))
|   i%ListCenter(3) = $lb($lb("A08829848","A088298480003",""))
|   i%ListCenter(4) = $lb($lb("U66700196","U667001960002",""))
|   i%ListCenter(5) = $lb($lb("U66700196","U667001960003",""))
|   r%ListCenter = "1@%Collection.ListOfObj"
|   r%ListCenter(1) = "3@LabCenter"
+-----------------------------------------------------
> set objFind = ##class(LabCenter).%New()
> set objFind.LabId="A08829848"
> set objFind.Center="A088298480003"
> zw objFind
objFind=<OBJECT REFERENCE>[5@LabCenter]
+----------------- general information ---------------
|      oref value: 5
|      class name: LabCenter
| reference count: 2
+----------------- attribute values ------------------
|             Center = "A088298480003"
|               Code = ""
|              LabId = "A08829848"
+-----------------------------------------------------
> w obj.Find(objFind)
3
> set objFindFake = ##class(LabCenter).%New()
> set objFindFake.LabId="FAKE"
> set objFindFake.Center="A088298480003"
> w obj.Find(objFindFake)
0

Thanks for your help.

Best regards,
Francisco López