Case-Insensitive Search Using std::ranges::find_if()

How can I make std::ranges::find_if() case-insensitive when searching through a container of strings?

To make std::ranges::find_if() case-insensitive when searching through a container of strings, you need to provide a predicate that performs a case-insensitive comparison.

Case-Insensitive Comparison Function

First, define a case-insensitive comparison function. You can use the std::tolower() function to convert characters to lowercase:

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <cctype>

bool caseInsensitiveCompare(char a, char b) {
  return std::tolower(a) == std::tolower(b);
}

Using std::ranges::find_if() with the Predicate

Next, use this function within a predicate for std::ranges::find_if():

#include <algorithm>
#include <iostream>
#include <vector>
#include <string>
#include <cctype>

bool caseInsensitiveCompare(char a, char b) {
  return std::tolower(a) == std::tolower(b);
}

bool caseInsensitiveStringCompare(
  const std::string& str,
  const std::string& target
) {
  return std::equal(
    str.begin(),
    str.end(),
    target.begin(),
    target.end(),
    caseInsensitiveCompare
  );
}

int main() {
  std::vector<std::string> words{
    "Apple", "banana", "Cherry" };

  std::string target = "BANANA";
  auto result = std::ranges::find_if(words,
    [&](const std::string& word) {
      return caseInsensitiveStringCompare(
        word, target
      ); 
  });

  if (result != words.end()) {
    std::cout << "Found: " << *result << "\n";
  } else {
    std::cout << "Not found\n";
  }
}
Found: banana

Explanation

In this example:

  • caseInsensitiveCompare() converts each character to lowercase before comparing.
  • caseInsensitiveStringCompare() uses std::equal() to compare two strings case-insensitively.
  • std::ranges::find_if() calls caseInsensitiveStringCompare() within a lambda function to perform the case-insensitive search.

Handling Mixed Case and Special Characters

This method works well for ASCII characters. For more complex scenarios involving Unicode characters, consider using libraries like ICU (International Components for Unicode) to handle case conversion and comparison.

By using a custom comparison function, you can effectively perform case-insensitive searches in a container of strings with std::ranges::find_if().

Search Algorithms

An introduction to the 8 main searching algorithms in the C++ standard library, including find(), find_if(), find_if_not(), find_first_of(), adjacent_find(), search_n(), search(), and find_end().

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Using std::ranges::find() with Custom Data Types
How can I use std::ranges::find() with custom data types that don't implement the equality operator ==?
Finding the Last Occurrence of an Element in a Container
How do I search for the last occurrence of an element using std::ranges::find() or std::find()?
Searching for Multiple Occurrences of a Value in a Container
What is the best way to search for multiple occurrences of a value in a container using standard library algorithms?
Searching for a Substring Appearing Multiple Times
How do I handle searching for a substring within a string when the substring can appear multiple times?
Boyer-Moore vs Boyer-Moore-Horspool Search Algorithms
What are the differences and benefits of using std::boyer_moore_searcher versus std::boyer_moore_horspool_searcher in practical scenarios?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant