Find item number of a list and compare to another list

I have tried tuple items and lists and so on, nothing is working for me tonight.

So here is what I am trying to do.

I have a custom property that contains a value, something like this. 000000 or 000001 or 000010

I have a list of results such as “Result1, Result2, Result3”

I want to pull the property (It is a client property) and find which Result item is the match. So if the property is “000000” it returns Result1 OR if the property is “000001” it returns Result2 and if the property is “000010” it returns returns Result3.

It should be efficient also, there are up to 64 Property values to search.

Does that make sense?

Right now I am doing a huge list of If, then Elseif to get my results. I would prefer a much easier way.

If I’m understanding the scenario correctly, you should be able to use the Location Property Wizard in BES Support to help create a property that will return the desired result based on a mapping of key value pairs that you provide.

You’d select the “Create a retrieved property that uses a custom relevance expression and maps the result using a key/value set” option, provide the relevance associated with your existing custom property, provide the new property name (i.e. the property that will return ‘Result1/2/3’, then supply the key-value pair mapping. The wizard would then create a custom property for you with efficient relevance that returns ‘Result1/2/3’ based on the existing custom property’s relevance.

I’m still trying to understand how this data is laid out.

In your case are the ‘00000’, ‘00001’, ‘00010’ actually index values in the list? Maybe it’s just coincidence you’ve represented these as if they were integers, are they actually integers we can use as indexes, or are these also just an arbitrary list?

One way I could visualize this is that each machine has two lists:

list1: “name1, name2, name3”
list2: “value1, value2, value3”

it sounds like you’re trying to represent this as key/value pairs - “name1=value1”, “name2=value2”, “name3=value3”…am I correct so far?

How will you be providing the key (name1, name2, or name3) that you wish to lookup in this key/value list?

I’ll be thinking about this, but there may be a way to handle this with tuple strings and indexing, but I want to make sure I’m understanding the problem space correctly

I agree the Location Property wizard might be useful in this case - providing the list of names/values don’t change too frequently. I also wanted to explore whether a solution is possible in pure relevance, let me know whether this is on the right track:

If we have an ordered list of plural results, we can represent it as a Tuple String. If you already have a Tuple String (values separated by comma and a space), then you can skip this first step:

q: ("name1"; "name2"; "name3")
A: name1
A: name2
A: name3
T: 0.330 ms
I: plural string

q: tuple string of ("name1"; "name2"; "name3")
A: name1, name2, name3
T: 0.314 ms
I: singular string

If we have two such lists, one with names and the other with values, we can put those two tuple strings together into a tuple where item 0 is the list of names and item 1 is the list of values:

q: (tuple string of ("name1"; "name2"; "name3"), tuple string of ("value1"; "value2"; "value3"))
A: ( name1, name2, name3 ), ( value1, value2, value3 )

Now that each item is a tuple string, we can count how many tuple string items there are. I’m going to only count the first list here, assuming they are the same length; but you could add some extra error handling here if needed to figure out which list is shorter.

q: (number of tuple string items of item 0 of it, item 0 of it, item 1 of it) of (tuple string of ("name1"; "name2"; "name3"), tuple string of ("value1"; "value2"; "value3"))
A: 3, ( name1, name2, name3 ), ( value1, value2, value3 )

Knowing the length of one of the lists, I can use the ‘integers in (0, length - 1)’ to build a list of indexes for items in the plural string. I’m not using that index yet, just building a list of the indexes in this step:

q: (integers in (0, number of tuple string items of item 0 of it -1), item 0 of it, item 1 of it) of (tuple string of ("name1"; "name2"; "name3"), tuple string of ("value1"; "value2"; "value3"))
A: 0, ( name1, name2, name3 ), ( value1, value2, value3 )
A: 1, ( name1, name2, name3 ), ( value1, value2, value3 )
A: 2, ( name1, name2, name3 ), ( value1, value2, value3 )

Now for the part that could scale badly, if these tuples are sufficiently long. I’m going to create a cross-product between them, matching up every tuple item in the first list against every tuple item in the second list. Here with a 3x3 set of lists, that returns a total of 9 items. If this were 10x10, there would be 100 items. If it’s 100x100, there would be 10000 items. So this can grow exponentially.
After the cross-product is generated, I filter to only those results where the index of the first tuple and the index of the second tuple both match the index count we’re generating - the first result gets item 0 from both lists, the second gets item 1 from both lists, etc.

q: (item 1 of it, item 2 of it) of (item 0 of it, tuple items of item 1 of it, tuple items of item 2 of it) whose (index of item 1 of it = item 0 of it and index of item 2 of it = item 0 of it) of (integers in (0, number of tuple string items of item 0 of it -1), item 0 of it, item 1 of it) of (tuple string of (“name1”; “name2”; “name3”), tuple string of (“value1”; “value2”; “value3”))
A: name1, value1
A: name2, value2
A: name3, value3

Now if we wanted to search these for only the value for ‘name2’ we can filter for that, and can return only the value (item 1 of it) matching the name:

q: items 1 of (it) whose (item 0 of it as string = "name1") of (item 1 of it, item 2 of it) of (item 0 of it, tuple items of item 1 of it, tuple items of item 2 of it) whose (index of item 1 of it = item 0 of it and index of item 2 of it = item 0 of it) of (integers in (0, number of tuple string items of item 0 of it -1), item 0 of it, item 1 of it) of (tuple string of ("name1"; "name2"; "name3"), tuple string of ("value1"; "value2"; "value3"))
A: value1

As far as scaling… this 3x3 example goes quickly

q: items 1 of (it) whose (item 0 of it as string = "name1") of (item 1 of it, item 2 of it) of (item 0 of it, tuple items of item 1 of it, tuple items of item 2 of it) whose (index of item 1 of it = item 0 of it and index of item 2 of it = item 0 of it) of (integers in (0, number of tuple string items of item 0 of it -1), item 0 of it, item 1 of it) of (tuple string of ("name1"; "name2"; "name3"), tuple string of ("value1"; "value2"; "value3"))
A: value1
T: 0.096 ms

Scaling it up to 12x12 is almost 10x slower. We can expect the speed to continue slowing down as the lists get longer but this is still pretty reasonable.


q: items 1 of (it) whose (item 0 of it as string = "name1") of (item 1 of it, item 2 of it) of (item 0 of it, tuple items of item 1 of it, tuple items of item 2 of it) whose (index of item 1 of it = item 0 of it and index of item 2 of it = item 0 of it) of (integers in (0, number of tuple string items of item 0 of it -1), item 0 of it, item 1 of it) of (tuple string of ("name1"; "name2"; "name3";"name4"; "name5"; "name6";"name7"; "name8"; "name9";"name10"; "name11"; "name12"), tuple string of ("value1"; "value2"; "value3";"value4"; "value5"; "value6";"value7"; "value8"; "value9";"value10"; "value11"; "value12"))
A: value1
T: 0.986 ms

Ok, I just logged in and have a ton of email. I will catch up on this thread in a bit. But, basically I am looking for an array to look up a value based on the value in a property.

If setting of client = 000000 then the lookup would return Result1
If setting of client = 000001 then the lookup would return Result2
If setting of client = 000010 then the lookup would return Result3

There is about 60 total available options for the client property. Right now I am using this…

if value of setting "MyCustomPropery" of client contains ":" then "Multiple Results" else if
value of setting "MyCustomPropery" of client contains "000000" then "Result1" else If
value of setting "MyCustomPropery" of client contains "000001" then "Result2" else If
value of setting "MyCustomPropery" of client contains "000010" then "Result3" else If

Yes, I use contains instead of equal because there can be some with systems with Result1:Result2. It is not necessary to look them up too but if we could, that would rock!

By the way, I live in AZ and usually log on around 8.

1 Like

Ok, I think I get it.
We can then make it somewhat more readable by creating a plural of tuples, and testing the condition on the first item of the tuple, and then returning the second item of matching results.

I want to point out the difference here between commas (elements of a tuple) versus semicolon (for plural results) in this list, and I’ve just added the “10” item because it happens to match an existing client setting on my machine.

q: settings of client
A: ILMT_Refresh_Sum=10
...
q: ("000000", "Result1"; "000001", "Result2"; "000010", "Result3"; "10", "Result4")
A: 000000, Result1
A: 000001, Result2
A: 000010, Result3
A: 10, Result4

Given this, we can return the ‘items 1’ of the plural results where ‘item 0’ of the tuple matches our condition:

q: concatenation ":" of items 1 of it whose (value of setting "ILMT_Refresh_Sum" of client| "" contains item 0 of it) of ("000000", "Result1"; "000001", "Result2"; "000010", "Result3"; "10", "Result4")
A: Result4

To illustrate what happens with multiple results I’m going to drop the ‘value of setting’ and just insert a static value to test:

q: concatenation ":" of items 1 of it whose ("000001:000010" contains item 0 of it) of ("000000", "Result1"; "000001", "Result2"; "000010", "Result3"; "10", "Result4")
A: Result2:Result3:Result4

Then we can test for your multiple matching results…

q: (if it contains ":" then "Multiple Matches" else it) of concatenation ":" of items 1 of it whose ("000001:000010" contains item 0 of it) of ("000000", "Result1"; "000001", "Result2"; "000010", "Result3"; "10", "Result4")
A: Multiple Matches
T: 5.988 ms
I: singular string

q: (if it contains ":" then "Multiple Matches" else it) of concatenation ":" of items 1 of it whose (value of setting "ILMT_Refresh_Sum" of client| "" contains item 0 of it) of ("000000", "Result1"; "000001", "Result2"; "000010", "Result3"; "10", "Result4")
A: Result4

I think you can use that last query, just replace the setting name and the values list. For readability, here’s the final query in indented form:

 (
   if
     it contains ":" 
   then
     "Multiple Matches" 
   else
     it
 )
 of concatenation ":" of items 1 of it 
 whose
 (
   value of setting "ILMT_Refresh_Sum" of client| "" contains item 0 of it
 )
 of 
 (
   "000000", "Result1";
   "000001", "Result2";
   "000010", "Result3";
       "10", "Result4"
 )
1 Like

I think this will work.
I am the only one on my team working today so I will have to try it later when things slow down.

You all rock!

1 Like

This works. Being that I was not able to actually list the items with the if. then, else if statements, I used the first one to indicate multiple matches so using your example minus the…

(
   if
     it contains ":" 
   then
     "Multiple Matches" 
   else
     it
 )
 of 

Worked perfectly.

1 Like