CONTAINS block for text strings

ok, here's a way better way to do it

and here's the xml

<blocks app="Snap! 6, https://snap.berkeley.edu" version="1"><block-definition s="to lowercase %&apos;value&apos;" type="reporter" category="operators"><header></header><code></code><translations></translations><inputs><input type="%s"></input></inputs><script><block s="doReport"><block s="evaluate"><block s="reportJSFunction"><list><l>value</l></list><l>return value.toLowerCase()</l></block><list><block var="value"/></list></block></block></script></block-definition><block-definition s="%&apos;txt&apos; contains %&apos;value&apos;" type="predicate" category="operators"><header></header><code></code><translations></translations><inputs><input type="%s"></input><input type="%s"></input></inputs><script><block s="doSetVar"><l>value</l><block s="reportMap"><block s="reifyReporter"><autolambda><custom-block s="to lowercase %s"><l></l></custom-block></autolambda><list></list></block><block s="reportTextSplit"><block var="value"/><l><option>letter</option></l></block></block></block><block s="doSetVar"><l>txt</l><block s="reportMap"><block s="reifyReporter"><autolambda><custom-block s="to lowercase %s"><l></l></custom-block></autolambda><list></list></block><block s="reportTextSplit"><block var="txt"/><l><option>letter</option></l></block></block></block><block s="doReport"><block s="reportGreaterThan"><block s="reportListLength"><block s="reportTextSplit"><block s="reportJoinWords"><block var="txt"/></block><block s="reportJoinWords"><block var="value"/></block></block></block><l>1</l></block></block></script><scripts><script x="96" y="286.83333333333337"><block s="doSetVar"><l>a</l><l>0</l></block><block s="doChangeVar"><l>a</l><l>1</l></block><block s="doIf"><block s="reportAnd"><block s="reportLessThan"><block s="reportUnicode"><block var="item"/></block><block s="reportUnicode"><l>Z</l></block></block><block s="reportGreaterThan"><block s="reportUnicode"><block var="item"/></block><l>64</l></block></block><script><block s="doReplaceInList"><block var="a"/><block var="variable"/><block s="reportUnicodeAsLetter"><block s="reportSum"><block s="reportUnicode"><block var="item"/></block><l>32</l></block></block></block></script></block></script><script x="139" y="211.49999999999994"><block s="doWarp"><script></script></block></script></scripts></block-definition></blocks>

Forum admins, can you split the posts to a new topic, maybe titled "Making of the CONTAINS (a substring) operator", or something similar?

There are several sub-questions going on here, so I can see why you want a split, but I don't see a very clear separation. Ironically, "making the CONTAINS block" is not one of the topics; it's a primitive! The topic you're seeing is "how do you get the INPUT LIST: variant of a block?" to which the answer is to drop a list over the arrowheads of a variadic input. Another piece of it is how to get case-independent searching, to which the answer (not given above, I think) is that CONTAINS uses = for comparisons, which is already case-independent! :~)

If I understand correctly, the CONTAINS primitive that you are referring to is the one from the 'red category' and it searches through items of a list. However this topic seems to be about searching for a substring of a text (not searching for an item of a list). Maybe the title should be "making of a (green, not red) CONTAINS block"?

Yes, you're right. But @ego-lay_atman-bay has solved it.

I've made it even smaller



xml

<blocks app="Snap! 6, https://snap.berkeley.edu" version="1"><block-definition s="%&apos;txt&apos; contains %&apos;value&apos;" type="predicate" category="operators"><header></header><code></code><translations></translations><inputs><input type="%s"></input><input type="%s"></input></inputs><script><block s="doReport"><block s="reportGreaterThan"><block s="reportListLength"><block s="reportTextSplit"><custom-block s="to lowercase %s"><block var="txt"/></custom-block><custom-block s="to lowercase %s"><block var="value"/></custom-block></block></block><l>1</l></block></block></script></block-definition><block-definition s="to lowercase %&apos;value&apos;" type="reporter" category="operators"><header></header><code></code><translations></translations><inputs><input type="%s"></input></inputs><script><block s="doReport"><block s="evaluate"><block s="reportJSFunction"><list><l>value</l></list><l>return value.toLowerCase()</l></block><list><block var="value"/></list></block></block></script></block-definition></blocks>

Very elegant!

Yes. I just wanted his solution to have a separate topic. That's why I suggested to make a split because the initial title doesn't mention it at all.

Oh I see.

Actually I was thinking of adding those blocks to the strings library. Is that okay, @ego-lay_atman-bay?

1 Like

sure

I ended up doing it in JS after all, so I could use the flag set by USE CASE-INDEPENDENT SEARCH, which is in the world's JS variables because at the time we didn't have the Variables library. I may rethink that, now that we do have it.

uh... can you explain that like you're talking to a five year old (note, I am not 5 years old, I know a lot more stuff than 5 year olds do)

I don't understand, either.

Why don't you add a block to convert strings to uppercase strings, too? You could use JavaScript's toUpperCase.

No, to the library. :stuck_out_tongue_winking_eye:

In the Strings library is the block

. The other blocks in the library check the flag it sets to decide whether to use case-indpendent (yay!) or case-sensitive (boo!) comparisons. That block doesn't set a Snap! variable; it does this:

var world=this.parentThatIsA(IDE_Morph);
world['stringLibCaseIndependentComparison'] = flag;

so the other blocks need to look up the flag in JS.

I wrote it that way because libraries can't include variables. But now we have the Variables library so I could have


and maybe I should do that.

When you're older, you'll understand. :~P

thanks, it now makes sense.

Yeah, I know, I could do that. But the reason for case conversion is case-independent comparison and that should be in lower case I think. Actually the official right thing is toLowerCase(toUpperCase()) because of the stupid ß which is equivalent to "ss" and becomes "SS" when converted to upper case. Maybe I'll make the Snap! lower case block do that round trip.

P.S. Reading this I see that I didn't really answer the question. Arguably every JS string function should be in this library. But in fact it's just the things I need; the library first appeared when we were doing web page scraping in BJC.

1 Like

But there is also the ẞ (the capital ß)!
By the way, it is is extremely hidden on every keyboard, because it has no real use.

Wait, what? Users may need things you do not need and I am quite sure a large number of users do not know JavaScript, if not most; and may also be struggling to find a Snap! implementation.