BR: StringArray::contains uses String::equals underneath the hood when ignoring case

This was unexpected behaviour.

bool StringArray::contains (StringRef stringToLookFor, bool ignoreCase) const
{
    return indexOf (stringToLookFor, ignoreCase) >= 0;
}

int StringArray::indexOf (StringRef stringToLookFor, bool ignoreCase, int i) const
{
    if (i < 0)
        i = 0;

    auto numElements = size();

    if (ignoreCase)
    {
        for (; i < numElements; ++i)
            if (strings.getReference(i).equalsIgnoreCase (stringToLookFor))

It’s worth mentioning that the StringArray searching functionality isn’t covered in the StringArray related unit tests (in juce_String.cpp → grep for beginTest ("StringArray");).

Some additional tests I recommend adding, including one that will demonstrate the issue:

            s.clear(); // For general code coverage
            expect (s.isEmpty());

            s = { "abcd", "qwerty", "asdf", "1234" };

            expect (s.contains ("ABCD", true));
            expect (! s.contains ("ABCD", false));
            expect (s.contains ("WERT", true)); // This fails when it shouldn't.
            expect (! s.contains ("WERT", false));
            expect (s.contains ("1234", true));
            expect (s.contains ("1234", false));
            expect (! s.contains ("Z", true));
            expect (! s.contains ("Z", false));
            expect (! s.contains ("z", true));
            expect (! s.contains ("z", false));

You know, the more I think about this the more I think the API is correct. Maybe there could be a containsSubstring (caseSensitiveOrNot) API?

I think the current behaviour is reasonable, and changing it might in turn break other code.

1 Like

Agreed.

That being said, would you consider adding an API with this concept: containsSubstring (caseSensitiveOrNot) ? Looking at all of the contained strings for a substring is my current need, which I worked around by doing (and created a standalone function to accomplish):

    for (const auto& s : myStrings)
        if (s.containsIgnoreCase (substringToLookFor))
            return true;

    return false;