Tinderbox Forum

Query code for part of values

I’m trying to create a query code, in which I want to capture all values (from a set) that contain “Sheriff” – i.e., a prefix before many names that fall under my $OfficialsPlayers values – and also exclude one name (e.g., Sheriff John Brown").

I thought that the following would work, just for querying the first part of what I’m seeking:

$Prototype=="pNotes" & $OfficialsPlayers.icontains("Sheriff")

However, this query didn’t produce any results, so I’m wondering what I’ve done wrong. Thanks…

What data-type is $OfficialsPlayers? The final ‘s’ suggests it is a List or sEt in which case a different strategy might be needed. Can you confirm the data types of the target attributes?

Yes, it’s a set.

For a List or Set, .icontains() works differently than from the more normal use with a String (as here). See the linked page.

Off to test something. An idea, follows separately.

1 Like

Thanks. I actually first referred to your page, and used it to construct the code I posted above. Honestly thought it would work; was a bit surprised when it didn’t.

To find all notes that include, case-insensitively, “shreiff” in one or more items in $OfficialsPlayers:

$Prototype=="pNotes" & $OfficialsPlayers.format(",").icontains("Sheriff")

But are you just after values regardless of where they occur? If so

Because you can’t match partial value if the source attribute is a list of value, as documented:

in which case it tests for set membership, i.e. matching to complete individual values rather than part of values.

1 Like

That worked!

In order to use this code, and exclude “Sheriff John Brown,” should I amend it with the following:

$Prototype=="pNotes" & $OfficialsPlayers.format(",").icontains("Sheriff") & !$OfficialsPlayers.contains("Sheriff John Brown")

?

Thanks again.

I just tried the above code, for including “Sheriff” (partial values) for $OfficialsPlayers (set), but it didn’t work. Then I tried this:

$Prototype=="pNotes" & $OfficialsPlayers.format(",").icontains("Sheriff") & !($OfficialsPlayers.contains("Sheriff John Brown"))

That didn’t work, either.

What should I use after $Prototype=="pNotes" & $OfficialsPlayers.format(",").icontains("Sheriff") to exclude “Sheriff John Brown” ?

Thank you, again.

Try:

$Prototype=="pNotes" & $OfficialsPlayers.format(",").icontains("Sheriff") & (!$OfficialsPlayers.contains("Sheriff John Brown"))

Thank you! It took a little while for the code to kick in, but then the agent produced the desired results. It’s terrific.

BTW, on your List/Set.icontains(“regex”) page, under the Testing “does not contain” and the “Use of parentheses after the ! …” section, the example shows the exclamation point just to the left of the first open parentheses. FWIW…

Many thanks again!

Yes, because that was from the source on which the example was based. I’m not sure what’s changed since but it does now appear that (!$AttrName) works better than !($AttrName).

But, stepping away from the magic aspect of code (i.e. not understood but just works) the issue here is that parentheses help Tinderbox understand your constraint. In theory:

!$OfficialsPlayers.contains("Sheriff John Brown")

intuitively ought to work. But ‘NOT’ query for regex can be problematic. Occasionally, Tinderbox may stumble at this step, so extra guiding parentheses are needed. In the past the syntax seemed to be !() but now appears to be (!). If you don’t want to guess if parentheses are needed with a negative test you can choose to always add parentheses as Tinderbox won’t mind.

I’ve updated the articles for String & list versions of .contains() and .icontains().

Got it…well, more or less!

I’m trying to wrap my head around how $MySet.format(",").icontains("") works. Right now, I’m thrilled that the query works! Thanks again.

@mwra where can I find an explanation of all the different .format conditions, e,g. “,”, "l’, “L”, etc. I’d love to learn the nuance here.

Date Formats, linked at the top of every aTbref page covers this.

Begs the question, where in the docs were you where I couldn’t find(a link to) what you needed? :slight_smile:

Yes, these are date formats, but i the context above we’re not using these for data. We’re using “,” to somehow format a String or set. it is not clear to me what the different flags are and when I can or should use them.

[Set].format(separator). converts a set to a string, inserting the string separator between elements. For example, $MySet.format(",") returns a comma-separated list.

I was confused by your use of ‘flags’. It is perhaps more useful to read first about format(). Even if you are more likely to use the dot-operator version, the original operator helps show how different source data types affect the result.

Here, you are referring without clarification_ to the formatting of lists which would have been a better question. I don’t mean that as rebuke … but garbage-in-garbage out. There are no format()-specific designators. What happens/what’s needed as input is entirely dependent on the source data type.

With a list, thus in Tinderbox a List-type or Set-type, the operator takes a single argument the ‘formatString’: this is an unevaluated string.formatString is the string used in the function’s output to replace the semicolon in the stored version of a list. Thus ", " places a comma+space between each term, whilst “\n” inserts a line break between each term etc. So " banana " would place space+banana+space between teach item, etc.

I’m confused as to how this is not clear in the existing documentation, though it seems there is potentially an issue over the user’s vs. author’s starting PoV. I’m open to suggestions as to how to make this better.

For specific data types, such as ‘Date’ type, there are a number of special format strings that can be used to give precise versions of formatString when rendering the source item(s).

1 Like

See Date.format("formatString") and then look at descriptions of Date Formats.

Cool. I just tied something and it worked perfectly

var:list vBenefitCity=collect_if(children,$ShortTitle=="Benefit",$StkhCity.format(", "));
var:list vBenefitResident=collect_if(children,$ShortTitle=="Benefit",$StkhResident.format(", "));
var:list vBenefitEntity=collect_if(children,$ShortTitle=="Benefit",$StkhEntity.format(", "));
var:list vBenefitCompany=collect_if(children,$ShortTitle=="Benefit",$StkhToyota.format(", "));

Formerly, I would have used a .replace(';",", ") to get rid of the “;”, `.format(", ")’ seems more efficient. Note, I introduce a space after the “,” and I get a comma separated lists from the sets:

image

1 Like